Change internal encoding of strings to CESU-8
JerryScript-DCO-1.0-Signed-off-by: Zsolt Borbély zsborbely.u-szeged@partner.samsung.com JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai.u-szeged@partner.samsung.com
This commit is contained in:
@@ -97,11 +97,13 @@ ecma_builtin_function_helper_get_arguments (const ecma_value_t *arguments_list_p
|
||||
ssize_t sz = ecma_string_to_utf8_string (str_p, start_p, (ssize_t) str_size);
|
||||
JERRY_ASSERT (sz >= 0);
|
||||
|
||||
lit_utf8_iterator_t iter = lit_utf8_iterator_create (start_p, str_size);
|
||||
lit_utf8_byte_t *current_p = start_p;
|
||||
const lit_utf8_byte_t *string_end_p = start_p + str_size;
|
||||
|
||||
while (!lit_utf8_iterator_is_eos (&iter))
|
||||
while (current_p < string_end_p)
|
||||
{
|
||||
ecma_char_t current_char = lit_utf8_iterator_read_next (&iter);
|
||||
ecma_char_t current_char;
|
||||
current_p += lit_read_code_unit_from_utf8 (current_p, ¤t_char);
|
||||
|
||||
if (current_char == ',')
|
||||
{
|
||||
@@ -197,33 +199,36 @@ ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p,
|
||||
ssize_t sz = ecma_string_to_utf8_string (arguments_str_p, start_p, (ssize_t) str_size);
|
||||
JERRY_ASSERT (sz >= 0);
|
||||
|
||||
lit_utf8_iterator_t iter = lit_utf8_iterator_create (start_p, str_size);
|
||||
ecma_length_t last_separator = lit_utf8_iterator_get_index (&iter);
|
||||
ecma_length_t end_position;
|
||||
lit_utf8_byte_t *current_p = start_p;
|
||||
lit_utf8_byte_t *last_separator = start_p;
|
||||
lit_utf8_byte_t *end_position;
|
||||
const lit_utf8_byte_t *string_end_p = start_p + str_size;
|
||||
ecma_string_t *param_str_p;
|
||||
|
||||
while (!lit_utf8_iterator_is_eos (&iter))
|
||||
while (current_p < string_end_p)
|
||||
{
|
||||
ecma_char_t current_char = lit_utf8_iterator_read_next (&iter);
|
||||
ecma_char_t current_char;
|
||||
lit_utf8_size_t read_size = lit_read_code_unit_from_utf8 (current_p, ¤t_char);
|
||||
|
||||
if (current_char == ',')
|
||||
{
|
||||
lit_utf8_iterator_decr (&iter);
|
||||
end_position = lit_utf8_iterator_get_index (&iter);
|
||||
end_position = current_p;
|
||||
|
||||
param_str_p = ecma_string_substr (arguments_str_p, last_separator, end_position);
|
||||
param_str_p = ecma_new_ecma_string_from_utf8 (last_separator,
|
||||
(lit_utf8_size_t) (end_position - last_separator));
|
||||
string_params_p[params_count] = ecma_string_trim (param_str_p);
|
||||
ecma_deref_ecma_string (param_str_p);
|
||||
|
||||
lit_utf8_iterator_incr (&iter);
|
||||
last_separator = lit_utf8_iterator_get_index (&iter);
|
||||
|
||||
last_separator = current_p + read_size;
|
||||
params_count++;
|
||||
}
|
||||
|
||||
current_p += read_size;
|
||||
}
|
||||
|
||||
end_position = lit_utf8_string_length (start_p, str_size);
|
||||
param_str_p = ecma_string_substr (arguments_str_p, last_separator, end_position);
|
||||
end_position = (lit_utf8_byte_t *) string_end_p;
|
||||
param_str_p = ecma_new_ecma_string_from_utf8 (last_separator,
|
||||
(lit_utf8_size_t) (end_position - last_separator));
|
||||
string_params_p[params_count] = ecma_string_trim (param_str_p);
|
||||
ecma_deref_ecma_string (param_str_p);
|
||||
params_count++;
|
||||
|
||||
@@ -852,6 +852,10 @@ ecma_builtin_global_object_decode_uri_helper (ecma_value_t uri __attr_unused___,
|
||||
output_size++;
|
||||
}
|
||||
}
|
||||
else if ((decoded_byte & LIT_UTF8_4_BYTE_MASK) == LIT_UTF8_4_BYTE_MARKER)
|
||||
{
|
||||
output_size += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
output_size++;
|
||||
@@ -861,27 +865,23 @@ ecma_builtin_global_object_decode_uri_helper (ecma_value_t uri __attr_unused___,
|
||||
if (ecma_is_completion_value_empty (ret_value))
|
||||
{
|
||||
MEM_DEFINE_LOCAL_ARRAY (output_start_p,
|
||||
output_size * 2,
|
||||
output_size,
|
||||
lit_utf8_byte_t);
|
||||
|
||||
input_char_p = input_start_p;
|
||||
lit_utf8_byte_t *output_char_p = output_start_p;
|
||||
lit_utf8_byte_t *output_type_p = output_start_p + output_size;
|
||||
|
||||
while (input_char_p < input_end_p)
|
||||
{
|
||||
/* Input decode. */
|
||||
if (*input_char_p != '%')
|
||||
{
|
||||
*output_type_p++ = URI_DECODE_ORIGINAL_BYTE;
|
||||
*output_char_p = *input_char_p;
|
||||
output_char_p++;
|
||||
input_char_p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
*output_type_p++ = URI_DECODE_DECODED_BYTE;
|
||||
|
||||
lit_code_point_t decoded_byte;
|
||||
|
||||
lit_read_code_point_from_hex (input_char_p + 1, 2, &decoded_byte);
|
||||
@@ -898,68 +898,95 @@ ecma_builtin_global_object_decode_uri_helper (ecma_value_t uri __attr_unused___,
|
||||
}
|
||||
else
|
||||
{
|
||||
*output_char_p = (lit_utf8_byte_t) decoded_byte;
|
||||
output_char_p++;
|
||||
*output_char_p++ = (lit_utf8_byte_t) decoded_byte;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*output_char_p = (lit_utf8_byte_t) decoded_byte;
|
||||
output_char_p++;
|
||||
}
|
||||
}
|
||||
uint32_t bytes_count;
|
||||
|
||||
JERRY_ASSERT (output_start_p + output_size == output_char_p);
|
||||
|
||||
bool valid_utf8 = lit_is_utf8_string_valid (output_start_p, output_size);
|
||||
|
||||
if (valid_utf8)
|
||||
{
|
||||
lit_utf8_iterator_t characters = lit_utf8_iterator_create (output_start_p, output_size);
|
||||
output_type_p = output_start_p + output_size;
|
||||
|
||||
while (!lit_utf8_iterator_is_eos (&characters))
|
||||
{
|
||||
bool original_byte = output_type_p[characters.buf_pos.offset] == URI_DECODE_ORIGINAL_BYTE;
|
||||
|
||||
ecma_char_t character = lit_utf8_iterator_read_next (&characters);
|
||||
|
||||
/* Surrogate fragments are allowed in JS, but not accepted by URI decoding. */
|
||||
if (!original_byte)
|
||||
if ((decoded_byte & LIT_UTF8_2_BYTE_MASK) == LIT_UTF8_2_BYTE_MARKER)
|
||||
{
|
||||
if (lit_is_code_unit_high_surrogate (character))
|
||||
{
|
||||
/* Note: stray high/low surrogate pairs are not allowed in the stream. */
|
||||
if (lit_utf8_iterator_is_eos (&characters))
|
||||
{
|
||||
valid_utf8 = false;
|
||||
break;
|
||||
}
|
||||
bytes_count = 2;
|
||||
}
|
||||
else if ((decoded_byte & LIT_UTF8_3_BYTE_MASK) == LIT_UTF8_3_BYTE_MARKER)
|
||||
{
|
||||
bytes_count = 3;
|
||||
}
|
||||
else if ((decoded_byte & LIT_UTF8_4_BYTE_MASK) == LIT_UTF8_4_BYTE_MARKER)
|
||||
{
|
||||
bytes_count = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_URI));
|
||||
break;
|
||||
}
|
||||
|
||||
if (output_type_p[characters.buf_pos.offset] == URI_DECODE_ORIGINAL_BYTE
|
||||
|| !lit_is_code_unit_low_surrogate (lit_utf8_iterator_read_next (&characters)))
|
||||
{
|
||||
valid_utf8 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (lit_is_code_unit_low_surrogate (character))
|
||||
lit_utf8_byte_t octets[LIT_UTF8_MAX_BYTES_IN_CODE_POINT];
|
||||
octets[0] = (lit_utf8_byte_t) decoded_byte;
|
||||
bool is_valid = true;
|
||||
|
||||
for (uint32_t i = 1; i < bytes_count; i++)
|
||||
{
|
||||
if (input_char_p >= input_end_p || *input_char_p != '%')
|
||||
{
|
||||
valid_utf8 = false;
|
||||
is_valid = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lit_code_point_t cp;
|
||||
lit_read_code_point_from_hex (input_char_p + 1, 2, &cp);
|
||||
|
||||
if ((cp & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
|
||||
{
|
||||
is_valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
octets[i] = (lit_utf8_byte_t) cp;
|
||||
input_char_p += URI_ENCODED_BYTE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_valid)
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_URI));
|
||||
break;
|
||||
}
|
||||
|
||||
lit_code_point_t cp;
|
||||
lit_read_code_point_from_utf8 (octets, bytes_count, &cp);
|
||||
|
||||
if ((bytes_count == 2 && cp <= LIT_UTF8_1_BYTE_CODE_POINT_MAX)
|
||||
|| (bytes_count == 3 && cp <= LIT_UTF8_2_BYTE_CODE_POINT_MAX)
|
||||
|| (bytes_count == 4 && cp <= LIT_UTF8_3_BYTE_CODE_POINT_MAX)
|
||||
|| lit_is_code_unit_high_surrogate ((ecma_char_t) cp)
|
||||
|| lit_is_code_unit_low_surrogate ((ecma_char_t) cp)
|
||||
|| cp > LIT_UNICODE_CODE_POINT_MAX)
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_URI));
|
||||
break;
|
||||
}
|
||||
|
||||
output_char_p += lit_code_point_to_cesu8 (cp, output_char_p);
|
||||
}
|
||||
}
|
||||
|
||||
if (valid_utf8)
|
||||
if (ecma_is_completion_value_empty (ret_value))
|
||||
{
|
||||
ecma_string_t *output_string_p = ecma_new_ecma_string_from_utf8 (output_start_p, output_size);
|
||||
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (output_string_p));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_URI));
|
||||
JERRY_ASSERT (output_start_p + output_size == output_char_p);
|
||||
|
||||
if (lit_is_cesu8_string_valid (output_start_p, output_size))
|
||||
{
|
||||
ecma_string_t *output_string_p = ecma_new_ecma_string_from_utf8 (output_start_p, output_size);
|
||||
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (output_string_p));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_URI));
|
||||
}
|
||||
}
|
||||
|
||||
MEM_FINALIZE_LOCAL_ARRAY (output_start_p);
|
||||
@@ -1056,20 +1083,53 @@ ecma_builtin_global_object_encode_uri_helper (ecma_value_t uri, /**< uri argumen
|
||||
*/
|
||||
|
||||
lit_utf8_byte_t *input_char_p = input_start_p;
|
||||
lit_utf8_byte_t *input_end_p = input_start_p + input_size;
|
||||
const lit_utf8_byte_t *input_end_p = input_start_p + input_size;
|
||||
lit_utf8_size_t output_length = 0;
|
||||
lit_code_point_t cp;
|
||||
ecma_char_t ch;
|
||||
lit_utf8_byte_t octets[LIT_UTF8_MAX_BYTES_IN_CODE_POINT];
|
||||
|
||||
while (input_char_p < input_end_p)
|
||||
{
|
||||
/*
|
||||
* We expect that the input is a valid UTF-8 sequence,
|
||||
* so we only need to reject stray surrogate pairs.
|
||||
*/
|
||||
/* Input validation, we need to reject stray surrogates. */
|
||||
input_char_p += lit_read_code_unit_from_utf8 (input_char_p, &ch);
|
||||
|
||||
/* Input validation. */
|
||||
if (*input_char_p <= LIT_UTF8_1_BYTE_CODE_POINT_MAX)
|
||||
if (lit_is_code_unit_low_surrogate (ch))
|
||||
{
|
||||
if (ecma_builtin_global_object_character_is_in (*input_char_p, unescaped_uri_bitset_p))
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_URI));
|
||||
break;
|
||||
}
|
||||
|
||||
cp = ch;
|
||||
|
||||
if (lit_is_code_unit_high_surrogate (ch))
|
||||
{
|
||||
if (input_char_p == input_end_p)
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_URI));
|
||||
break;
|
||||
}
|
||||
|
||||
ecma_char_t next_ch;
|
||||
lit_utf8_size_t read_size = lit_read_code_unit_from_utf8 (input_char_p, &next_ch);
|
||||
|
||||
if (lit_is_code_unit_low_surrogate (next_ch))
|
||||
{
|
||||
cp = lit_convert_surrogate_pair_to_code_point (ch, next_ch);
|
||||
input_char_p += read_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_URI));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lit_utf8_size_t utf_size = lit_code_point_to_utf8 (cp, octets);
|
||||
|
||||
if (utf_size == 1)
|
||||
{
|
||||
if (ecma_builtin_global_object_character_is_in (octets[0], unescaped_uri_bitset_p))
|
||||
{
|
||||
output_length++;
|
||||
}
|
||||
@@ -1078,28 +1138,10 @@ ecma_builtin_global_object_encode_uri_helper (ecma_value_t uri, /**< uri argumen
|
||||
output_length += URI_ENCODED_BYTE_SIZE;
|
||||
}
|
||||
}
|
||||
else if (*input_char_p == (LIT_UTF8_3_BYTE_MARKER + (LIT_UTF16_HIGH_SURROGATE_MARKER >> 12)))
|
||||
{
|
||||
/* The next character is in the [0xd000, 0xdfff] range. */
|
||||
output_length += URI_ENCODED_BYTE_SIZE;
|
||||
input_char_p++;
|
||||
JERRY_ASSERT (input_char_p < input_end_p);
|
||||
JERRY_ASSERT ((*input_char_p & LIT_UTF8_EXTRA_BYTE_MASK) == LIT_UTF8_EXTRA_BYTE_MARKER);
|
||||
|
||||
/* If this condition is true, the next character is >= LIT_UTF16_HIGH_SURROGATE_MIN. */
|
||||
if (*input_char_p & 0x20)
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_URI));
|
||||
break;
|
||||
}
|
||||
output_length += URI_ENCODED_BYTE_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
output_length += URI_ENCODED_BYTE_SIZE;
|
||||
output_length += utf_size * URI_ENCODED_BYTE_SIZE;
|
||||
}
|
||||
|
||||
input_char_p++;
|
||||
}
|
||||
|
||||
if (ecma_is_completion_value_empty (ret_value))
|
||||
@@ -1114,26 +1156,43 @@ ecma_builtin_global_object_encode_uri_helper (ecma_value_t uri, /**< uri argumen
|
||||
while (input_char_p < input_end_p)
|
||||
{
|
||||
/* Input decode. */
|
||||
input_char_p += lit_read_code_unit_from_utf8 (input_char_p, &ch);
|
||||
cp = ch;
|
||||
|
||||
if (*input_char_p <= LIT_UTF8_1_BYTE_CODE_POINT_MAX)
|
||||
if (lit_is_code_unit_high_surrogate (ch))
|
||||
{
|
||||
if (ecma_builtin_global_object_character_is_in (*input_char_p, unescaped_uri_bitset_p))
|
||||
ecma_char_t next_ch;
|
||||
lit_utf8_size_t read_size = lit_read_code_unit_from_utf8 (input_char_p, &next_ch);
|
||||
|
||||
if (lit_is_code_unit_low_surrogate (next_ch))
|
||||
{
|
||||
*output_char_p++ = *input_char_p;
|
||||
cp = lit_convert_surrogate_pair_to_code_point (ch, next_ch);
|
||||
input_char_p += read_size;
|
||||
}
|
||||
}
|
||||
|
||||
lit_utf8_size_t utf_size = lit_code_point_to_utf8 (cp, octets);
|
||||
|
||||
if (utf_size == 1)
|
||||
{
|
||||
if (ecma_builtin_global_object_character_is_in (octets[0], unescaped_uri_bitset_p))
|
||||
{
|
||||
*output_char_p++ = octets[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_builtin_global_object_byte_to_hex (output_char_p, *input_char_p);
|
||||
ecma_builtin_global_object_byte_to_hex (output_char_p, octets[0]);
|
||||
output_char_p += URI_ENCODED_BYTE_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_builtin_global_object_byte_to_hex (output_char_p, *input_char_p);
|
||||
output_char_p += URI_ENCODED_BYTE_SIZE;
|
||||
for (uint32_t i = 0; i < utf_size; i++)
|
||||
{
|
||||
ecma_builtin_global_object_byte_to_hex (output_char_p, octets[i]);
|
||||
output_char_p += URI_ENCODED_BYTE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
input_char_p++;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (output_start_p + output_length == output_char_p);
|
||||
|
||||
@@ -186,7 +186,7 @@ ecma_builtin_json_parse_string (ecma_json_token_t *token_p) /**< token argument
|
||||
}
|
||||
|
||||
current_p += 5;
|
||||
write_p += lit_code_point_to_utf8 (code_point, write_p);
|
||||
write_p += lit_code_point_to_cesu8 (code_point, write_p);
|
||||
continue;
|
||||
/* FALLTHRU */
|
||||
}
|
||||
@@ -199,57 +199,6 @@ ecma_builtin_json_parse_string (ecma_json_token_t *token_p) /**< token argument
|
||||
*write_p++ = *current_p++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Post processing surrogate pairs.
|
||||
*
|
||||
* The general issue is, that surrogate fragments can come from
|
||||
* the original stream and can be constructed by \u sequences
|
||||
* as well. We need to construct code points from them.
|
||||
*
|
||||
* Example: JSON.parse ('"\\ud801\udc00"') === "\ud801\udc00"
|
||||
* The first \u is parsed by JSON, the second is by the lexer.
|
||||
*
|
||||
* The rewrite happens in-place, since the write pointer is always
|
||||
* precede the read-pointer. We also cannot create an UTF8 iterator,
|
||||
* because the lit_is_utf8_string_valid assertion may fail.
|
||||
*/
|
||||
|
||||
lit_utf8_byte_t *read_p = token_p->u.string.start_p;
|
||||
lit_utf8_byte_t *read_end_p = write_p;
|
||||
write_p = read_p;
|
||||
|
||||
while (read_p < read_end_p)
|
||||
{
|
||||
lit_code_point_t code_point;
|
||||
read_p += lit_read_code_point_from_utf8 (read_p,
|
||||
(lit_utf8_size_t) (read_end_p - read_p),
|
||||
&code_point);
|
||||
|
||||
/* The lit_is_code_unit_high_surrogate expects ecma_char_t argument
|
||||
so code_points above maximum UTF16 code unit must not be tested. */
|
||||
if (read_p < read_end_p
|
||||
&& code_point <= LIT_UTF16_CODE_UNIT_MAX
|
||||
&& lit_is_code_unit_high_surrogate ((ecma_char_t) code_point))
|
||||
{
|
||||
lit_code_point_t next_code_point;
|
||||
lit_utf8_size_t next_code_point_size = lit_read_code_point_from_utf8 (read_p,
|
||||
(lit_utf8_size_t) (read_end_p - read_p),
|
||||
&next_code_point);
|
||||
|
||||
if (next_code_point <= LIT_UTF16_CODE_UNIT_MAX
|
||||
&& lit_is_code_unit_low_surrogate ((ecma_char_t) next_code_point))
|
||||
{
|
||||
code_point = lit_convert_surrogate_pair_to_code_point ((ecma_char_t) code_point,
|
||||
(ecma_char_t) next_code_point);
|
||||
read_p += next_code_point_size;
|
||||
}
|
||||
}
|
||||
write_p += lit_code_point_to_utf8 (code_point, write_p);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (lit_is_utf8_string_valid (token_p->u.string.start_p,
|
||||
(lit_utf8_size_t) (write_p - token_p->u.string.start_p)));
|
||||
|
||||
token_p->u.string.size = (lit_utf8_size_t) (write_p - token_p->u.string.start_p);
|
||||
token_p->current_p = current_p + 1;
|
||||
token_p->type = string_token;
|
||||
|
||||
@@ -2306,26 +2306,9 @@ ecma_builtin_string_prototype_object_conversion_helper (ecma_value_t this_arg, /
|
||||
{
|
||||
ecma_char_t character = lit_utf8_iterator_read_next (&input_iterator);
|
||||
ecma_char_t character_buffer[LIT_MAXIMUM_OTHER_CASE_LENGTH];
|
||||
lit_utf8_byte_t utf8_byte_buffer[LIT_UTF8_MAX_BYTES_IN_CODE_POINT];
|
||||
lit_utf8_byte_t utf8_byte_buffer[LIT_CESU8_MAX_BYTES_IN_CODE_POINT];
|
||||
lit_utf8_size_t character_length;
|
||||
|
||||
/*
|
||||
* We need to keep surrogate pairs. Surrogates are never converted,
|
||||
* regardless they form a valid pair or not.
|
||||
*/
|
||||
if (lit_is_code_unit_high_surrogate (character))
|
||||
{
|
||||
ecma_char_t next_character = lit_utf8_iterator_peek_next (&input_iterator);
|
||||
|
||||
if (lit_is_code_unit_low_surrogate (next_character))
|
||||
{
|
||||
lit_code_point_t surrogate_code_point = lit_convert_surrogate_pair_to_code_point (character, next_character);
|
||||
output_length += lit_code_point_to_utf8 (surrogate_code_point, utf8_byte_buffer);
|
||||
lit_utf8_iterator_incr (&input_iterator);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (lower_case)
|
||||
{
|
||||
character_length = lit_char_to_lower_case (character,
|
||||
@@ -2364,23 +2347,6 @@ ecma_builtin_string_prototype_object_conversion_helper (ecma_value_t this_arg, /
|
||||
ecma_char_t character_buffer[LIT_MAXIMUM_OTHER_CASE_LENGTH];
|
||||
lit_utf8_size_t character_length;
|
||||
|
||||
/*
|
||||
* We need to keep surrogate pairs. Surrogates are never converted,
|
||||
* regardless they form a valid pair or not.
|
||||
*/
|
||||
if (lit_is_code_unit_high_surrogate (character))
|
||||
{
|
||||
ecma_char_t next_character = lit_utf8_iterator_peek_next (&input_iterator);
|
||||
|
||||
if (lit_is_code_unit_low_surrogate (next_character))
|
||||
{
|
||||
lit_code_point_t surrogate_code_point = lit_convert_surrogate_pair_to_code_point (character, next_character);
|
||||
output_char_p += lit_code_point_to_utf8 (surrogate_code_point, output_char_p);
|
||||
lit_utf8_iterator_incr (&input_iterator);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (lower_case)
|
||||
{
|
||||
character_length = lit_char_to_lower_case (character,
|
||||
@@ -2398,7 +2364,7 @@ ecma_builtin_string_prototype_object_conversion_helper (ecma_value_t this_arg, /
|
||||
|
||||
for (lit_utf8_size_t i = 0; i < character_length; i++)
|
||||
{
|
||||
output_char_p += lit_code_point_to_utf8 (character_buffer[i], output_char_p);
|
||||
output_char_p += lit_code_unit_to_utf8 (character_buffer[i], output_char_p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2503,60 +2469,8 @@ ecma_builtin_string_prototype_object_trim (ecma_value_t this_arg) /**< this argu
|
||||
|
||||
ecma_string_t *original_string_p = ecma_get_string_from_value (to_string_val);
|
||||
|
||||
/* 3 */
|
||||
const lit_utf8_size_t size = ecma_string_get_size (original_string_p);
|
||||
|
||||
/* Workaround: avoid repeated call of ecma_string_get_char_at_pos() because its overhead */
|
||||
lit_utf8_byte_t *original_utf8_str_p = (lit_utf8_byte_t *) mem_heap_alloc_block (size + 1,
|
||||
MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
ssize_t sz = ecma_string_to_utf8_string (original_string_p, original_utf8_str_p, (ssize_t) size);
|
||||
JERRY_ASSERT (sz >= 0);
|
||||
|
||||
const ecma_length_t length = lit_utf8_string_length (original_utf8_str_p, size);
|
||||
|
||||
lit_utf8_iterator_t iter = lit_utf8_iterator_create (original_utf8_str_p, size);
|
||||
|
||||
uint32_t prefix = 0, postfix = 0;
|
||||
uint32_t new_len = 0;
|
||||
|
||||
while (!lit_utf8_iterator_is_eos (&iter))
|
||||
{
|
||||
ecma_char_t current_char = lit_utf8_iterator_read_next (&iter);
|
||||
|
||||
if (lit_char_is_white_space (current_char)
|
||||
|| lit_char_is_line_terminator (current_char))
|
||||
{
|
||||
prefix++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lit_utf8_iterator_seek_eos (&iter);
|
||||
while (!lit_utf8_iterator_is_bos (&iter))
|
||||
{
|
||||
ecma_char_t current_char = lit_utf8_iterator_read_prev (&iter);
|
||||
|
||||
if (lit_char_is_white_space (current_char)
|
||||
|| lit_char_is_line_terminator (current_char))
|
||||
{
|
||||
postfix++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
new_len = prefix < length ? length - prefix - postfix : 0;
|
||||
|
||||
ecma_string_t *new_str_p = ecma_string_substr (original_string_p, prefix, prefix + new_len);
|
||||
|
||||
/* 4 */
|
||||
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (new_str_p));
|
||||
|
||||
mem_heap_free_block (original_utf8_str_p);
|
||||
ecma_string_t *trimmed_string_p = ecma_string_trim (original_string_p);
|
||||
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (trimmed_string_p));
|
||||
|
||||
ECMA_FINALIZE (to_string_val);
|
||||
ECMA_FINALIZE (check_coercible_val);
|
||||
|
||||
@@ -67,15 +67,13 @@ ecma_builtin_string_object_from_char_code (ecma_value_t this_arg __attr_unused__
|
||||
}
|
||||
else
|
||||
{
|
||||
lit_utf8_size_t utf8_buf_size = args_number * LIT_UTF8_MAX_BYTES_IN_CODE_UNIT;
|
||||
lit_utf8_size_t utf8_buf_size = args_number * LIT_CESU8_MAX_BYTES_IN_CODE_UNIT;
|
||||
|
||||
MEM_DEFINE_LOCAL_ARRAY (utf8_buf_p,
|
||||
utf8_buf_size,
|
||||
lit_utf8_byte_t);
|
||||
|
||||
lit_utf8_size_t utf8_buf_used = 0;
|
||||
lit_utf8_size_t last_code_unit_size = 0;
|
||||
ecma_char_t high_surrogate = 0;
|
||||
|
||||
for (ecma_length_t arg_index = 0;
|
||||
arg_index < args_number && ecma_is_completion_value_empty (ret_value);
|
||||
@@ -86,37 +84,10 @@ ecma_builtin_string_object_from_char_code (ecma_value_t this_arg __attr_unused__
|
||||
uint32_t uint32_char_code = ecma_number_to_uint32 (arg_num);
|
||||
ecma_char_t code_unit = (uint16_t) uint32_char_code;
|
||||
|
||||
if (high_surrogate && lit_is_code_unit_low_surrogate (code_unit))
|
||||
{
|
||||
JERRY_ASSERT (last_code_unit_size > 0);
|
||||
JERRY_ASSERT (utf8_buf_used >= last_code_unit_size);
|
||||
|
||||
utf8_buf_used -= last_code_unit_size;
|
||||
|
||||
JERRY_ASSERT (utf8_buf_used <= utf8_buf_size - LIT_UTF8_MAX_BYTES_IN_CODE_POINT);
|
||||
|
||||
lit_code_point_t code_point = lit_convert_surrogate_pair_to_code_point (high_surrogate, code_unit);
|
||||
|
||||
last_code_unit_size = lit_code_point_to_utf8 (code_point, utf8_buf_p + utf8_buf_used);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (utf8_buf_used <= utf8_buf_size - LIT_UTF8_MAX_BYTES_IN_CODE_UNIT);
|
||||
last_code_unit_size = lit_code_unit_to_utf8 (code_unit, utf8_buf_p + utf8_buf_used);
|
||||
}
|
||||
|
||||
utf8_buf_used += last_code_unit_size;
|
||||
JERRY_ASSERT (utf8_buf_used <= utf8_buf_size - LIT_UTF8_MAX_BYTES_IN_CODE_UNIT);
|
||||
utf8_buf_used += lit_code_unit_to_utf8 (code_unit, utf8_buf_p + utf8_buf_used);
|
||||
JERRY_ASSERT (utf8_buf_used <= utf8_buf_size);
|
||||
|
||||
if (lit_is_code_unit_high_surrogate (code_unit))
|
||||
{
|
||||
high_surrogate = code_unit;
|
||||
}
|
||||
else
|
||||
{
|
||||
high_surrogate = 0;
|
||||
}
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user