Implement TrimStart TrimEnd and aliases (#4102)

Based on: https://tc39.es/ecma262/#sec-string.prototype.trim

JerryScript-DCO-1.0-Signed-off-by: Bela Toth tbela@inf.u-szeged.hu
This commit is contained in:
Tóth Béla 2020-08-25 13:10:36 +02:00 committed by GitHub
parent 85981457e6
commit 09c8d28b2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 172 additions and 91 deletions

View File

@ -729,13 +729,11 @@ ecma_number_parse_int (const lit_utf8_byte_t *string_buff, /**< routine's first
return ecma_make_nan_value ();
}
const lit_utf8_byte_t *string_curr_p = string_buff;
/* 2. Remove leading whitespace. */
ecma_string_trim_helper (&string_curr_p, &string_buff_size);
const lit_utf8_byte_t *string_end_p = string_curr_p + string_buff_size;
const lit_utf8_byte_t *start_p = string_curr_p;
const lit_utf8_byte_t *string_end_p = string_buff + string_buff_size;
const lit_utf8_byte_t *start_p = ecma_string_trim_front (string_buff, string_end_p);
const lit_utf8_byte_t *string_curr_p = start_p;
const lit_utf8_byte_t *end_p = string_end_p;
if (string_curr_p >= string_end_p)
@ -906,13 +904,11 @@ ecma_number_parse_float (const lit_utf8_byte_t *string_buff, /**< routine's firs
return ecma_make_nan_value ();
}
const lit_utf8_byte_t *str_curr_p = string_buff;
/* 2. Remove leading whitespace. */
ecma_string_trim_helper (&str_curr_p, &string_buff_size);
const lit_utf8_byte_t *str_end_p = str_curr_p + string_buff_size;
const lit_utf8_byte_t *start_p = str_curr_p;
const lit_utf8_byte_t *str_end_p = string_buff + string_buff_size;
const lit_utf8_byte_t *start_p = ecma_string_trim_front (string_buff, str_end_p);
const lit_utf8_byte_t *str_curr_p = start_p;
const lit_utf8_byte_t *end_p = str_end_p;
bool sign = false;

View File

@ -2426,49 +2426,81 @@ ecma_string_substr (const ecma_string_t *string_p, /**< pointer to an ecma strin
* Helper function for trimming.
*
* Used by:
* - ecma_string_trim
* - ecma_utf8_string_to_number
* - ecma_string_trim_helper
* - ecma_builtin_global_object_parse_int
* - ecma_builtin_global_object_parse_float
*
* @return position of the first non whitespace character.
*/
void
const lit_utf8_byte_t *
ecma_string_trim_front (const lit_utf8_byte_t *start_p, /**< current string's start position */
const lit_utf8_byte_t *end_p) /**< current string's end position */
{
ecma_char_t ch;
while (start_p < end_p)
{
lit_utf8_size_t read_size = lit_read_code_unit_from_utf8 (start_p, &ch);
if (!lit_char_is_white_space (ch))
{
break;
}
start_p += read_size;
}
return start_p;
} /* ecma_string_trim_front */
/**
* Helper function for trimming.
*
* Used by:
* - ecma_string_trim_helper
*
* @return position of the last non whitespace character.
*/
const lit_utf8_byte_t *
ecma_string_trim_back (const lit_utf8_byte_t *start_p, /**< current string's start position */
const lit_utf8_byte_t *end_p) /**< current string's end position */
{
ecma_char_t ch;
while (end_p > start_p)
{
lit_utf8_size_t read_size = lit_read_prev_code_unit_from_utf8 (end_p, &ch);
if (!lit_char_is_white_space (ch))
{
break;
}
end_p -= read_size;
}
return end_p;
} /* ecma_string_trim_back */
/**
* Helper function for trimming.
*
* Used by:
* - ecma_string_trim
* - ecma_utf8_string_to_number
*/
inline void JERRY_ATTR_ALWAYS_INLINE
ecma_string_trim_helper (const lit_utf8_byte_t **utf8_str_p, /**< [in, out] current string position */
lit_utf8_size_t *utf8_str_size) /**< [in, out] size of the given string */
{
ecma_char_t ch;
lit_utf8_size_t read_size;
const lit_utf8_byte_t *nonws_start_p = *utf8_str_p + *utf8_str_size;
const lit_utf8_byte_t *current_p = *utf8_str_p;
const lit_utf8_byte_t *end_p = *utf8_str_p + *utf8_str_size;
const lit_utf8_byte_t *start_p = *utf8_str_p;
while (current_p < nonws_start_p)
{
read_size = lit_read_code_unit_from_utf8 (current_p, &ch);
const lit_utf8_byte_t *new_start_p = ecma_string_trim_front (start_p, end_p);
const lit_utf8_byte_t *new_end_p = ecma_string_trim_back (new_start_p, end_p);
if (!lit_char_is_white_space (ch))
{
nonws_start_p = current_p;
break;
}
current_p += read_size;
}
current_p = *utf8_str_p + *utf8_str_size;
while (current_p > nonws_start_p)
{
read_size = lit_read_prev_code_unit_from_utf8 (current_p, &ch);
if (!lit_char_is_white_space (ch))
{
break;
}
current_p -= read_size;
}
*utf8_str_p = nonws_start_p;
*utf8_str_size = (lit_utf8_size_t) (current_p - nonws_start_p);
*utf8_str_size = (lit_utf8_size_t) (new_end_p - new_start_p);
*utf8_str_p = new_start_p;
} /* ecma_string_trim_helper */
/**

View File

@ -397,6 +397,8 @@ lit_magic_string_id_t ecma_get_string_magic (const ecma_string_t *string_p);
lit_string_hash_t ecma_string_hash (const ecma_string_t *string_p);
ecma_string_t *ecma_string_substr (const ecma_string_t *string_p, lit_utf8_size_t start_pos, lit_utf8_size_t end_pos);
const lit_utf8_byte_t *ecma_string_trim_front (const lit_utf8_byte_t *start_p, const lit_utf8_byte_t *end_p);
const lit_utf8_byte_t *ecma_string_trim_back (const lit_utf8_byte_t *start_p, const lit_utf8_byte_t *end_p);
void ecma_string_trim_helper (const lit_utf8_byte_t **utf8_str_p,
lit_utf8_size_t *utf8_str_size);
ecma_string_t *ecma_string_trim (const ecma_string_t *string_p);

View File

@ -18,7 +18,9 @@
#include "ecma-container-object.h"
#include "ecma-array-object.h"
#include "ecma-typedarray-object.h"
#include "ecma-string-object.h"
#include "ecma-gc.h"
#include "ecma-helpers.h"
#include "lit-char-helpers.h"
#if ENABLED (JERRY_ESNEXT)
@ -44,7 +46,9 @@ enum
ECMA_INTRINSIC_ARRAY_TO_STRING,
ECMA_INTRINSIC_DATE_TO_UTC_STRING,
ECMA_INTRINSIC_PARSE_FLOAT,
ECMA_INTRINSIC_PARSE_INT
ECMA_INTRINSIC_PARSE_INT,
ECMA_INTRINSIC_STRING_TRIM_START,
ECMA_INTRINSIC_STRING_TRIM_END,
};
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-intrinsic.inc.h"
@ -206,6 +210,48 @@ ecma_builtin_intrinsic_dispatch_routine (uint16_t builtin_routine_id, /**< built
return ecma_date_value_to_utc_string (*prim_value_p);
}
case ECMA_INTRINSIC_STRING_TRIM_START:
case ECMA_INTRINSIC_STRING_TRIM_END:
{
ecma_value_t coercible = ecma_op_check_object_coercible (this_arg);
if (ECMA_IS_VALUE_ERROR (coercible))
{
return coercible;
}
ecma_string_t *to_str_p = ecma_op_to_string (this_arg);
if (to_str_p == NULL)
{
return ECMA_VALUE_ERROR;
}
ECMA_STRING_TO_UTF8_STRING (to_str_p, start_p, input_start_size);
lit_utf8_size_t size;
const lit_utf8_byte_t *input_start_p = start_p;
const lit_utf8_byte_t *input_str_end_p = start_p + input_start_size;
ecma_string_t *ret_str_p;
if (builtin_routine_id == ECMA_INTRINSIC_STRING_TRIM_START)
{
const lit_utf8_byte_t *new_start_p = ecma_string_trim_front (input_start_p, input_str_end_p);
size = (lit_utf8_size_t) (input_str_end_p - new_start_p);
ret_str_p = ecma_new_ecma_string_from_utf8 (new_start_p, size);
}
else
{
const lit_utf8_byte_t *new_end_p = ecma_string_trim_back (input_start_p, input_str_end_p);
size = (lit_utf8_size_t) (new_end_p - input_start_p);
ret_str_p = ecma_new_ecma_string_from_utf8 (input_start_p, size);
}
ECMA_FINALIZE_UTF8_STRING (start_p, input_start_size);
ecma_value_t result = ecma_make_string_value (ret_str_p);
ecma_deref_ecma_string (to_str_p);
return result;
}
default:
{
JERRY_ASSERT (builtin_routine_id == ECMA_INTRINSIC_PARSE_INT
@ -236,7 +282,6 @@ ecma_builtin_intrinsic_dispatch_routine (uint16_t builtin_routine_id, /**< built
ECMA_FINALIZE_UTF8_STRING (string_buff, string_buff_size);
ecma_deref_ecma_string (str_p);
return result;
}
}

View File

@ -74,6 +74,8 @@ ROUTINE (LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES, ECMA_INTRINSIC_ARRAY_
ROUTINE (LIT_INTERNAL_MAGIC_STRING_TYPEDARRAY_PROTOTYPE_VALUES, ECMA_INTRINSIC_TYPEDARRAY_PROTOTYPE_VALUES, 0, 0)
ROUTINE (LIT_INTERNAL_MAGIC_STRING_SET_PROTOTYPE_VALUES, ECMA_INTRINSIC_SET_PROTOTYPE_VALUES, 0, 0)
ROUTINE (LIT_INTERNAL_MAGIC_STRING_MAP_PROTOTYPE_ENTRIES, ECMA_INTRINSIC_MAP_PROTOTYPE_ENTRIES, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TRIM_START, ECMA_INTRINSIC_STRING_TRIM_START, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TRIM_END, ECMA_INTRINSIC_STRING_TRIM_END, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ECMA_INTRINSIC_ARRAY_TO_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_UTC_STRING_UL, ECMA_INTRINSIC_DATE_TO_UTC_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_PARSE_FLOAT, ECMA_INTRINSIC_PARSE_FLOAT, 1, 1)

View File

@ -76,6 +76,15 @@ ROUTINE (LIT_MAGIC_STRING_CODE_POINT_AT, ECMA_STRING_PROTOTYPE_CODE_POINT_AT, 1,
ROUTINE (LIT_MAGIC_STRING_PAD_START, ECMA_STRING_PROTOTYPE_PAD_START, 2, 1)
ROUTINE (LIT_MAGIC_STRING_PAD_END, ECMA_STRING_PROTOTYPE_PAD_END, 2, 1)
ROUTINE (LIT_GLOBAL_SYMBOL_ITERATOR, ECMA_STRING_PROTOTYPE_ITERATOR, 0, 0)
INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TRIM_START, LIT_MAGIC_STRING_TRIM_START,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TRIM_LEFT, LIT_MAGIC_STRING_TRIM_START,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TRIM_END, LIT_MAGIC_STRING_TRIM_END,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TRIM_RIGHT, LIT_MAGIC_STRING_TRIM_END,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ESNEXT) */
#endif /* ENABLED (JERRY_BUILTIN_STRING) */

View File

@ -531,6 +531,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SPECIES, "species")
#if ENABLED (JERRY_BUILTIN_NUMBER)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_FIXED_UL, "toFixed")
#endif
#if ENABLED (JERRY_ESNEXT)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TRIM_END, "trimEnd")
#endif
#if ENABLED (JERRY_BUILTIN_REGEXP) && ENABLED (JERRY_ESNEXT)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UNICODE, "unicode")
#endif
@ -598,6 +601,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_UINT8_UL, "setUint8")
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SUBARRAY, "subarray")
#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_STRING_UL, "toString")
#if ENABLED (JERRY_BUILTIN_STRING) && ENABLED (JERRY_ESNEXT)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TRIM_LEFT, "trimLeft")
#endif
#if ENABLED (JERRY_BUILTIN_ANNEXB)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UNESCAPE, "unescape")
#endif
@ -668,6 +674,12 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_STRINGIFY, "stringify")
#if ENABLED (JERRY_BUILTIN_STRING)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SUBSTRING, "substring")
#endif
#if ENABLED (JERRY_BUILTIN_STRING) && ENABLED (JERRY_ESNEXT)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TRIM_RIGHT, "trimRight")
#endif
#if ENABLED (JERRY_ESNEXT)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TRIM_START, "trimStart")
#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UNDEFINED, "undefined")
#if ENABLED (JERRY_BUILTIN_TYPEDARRAY)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_INT16_ARRAY_UL, "Int16Array")

View File

@ -206,6 +206,7 @@ LIT_MAGIC_STRING_SET_INT8_UL = "setInt8"
LIT_MAGIC_STRING_SET_YEAR_UL = "setYear"
LIT_MAGIC_STRING_SPECIES = "species"
LIT_MAGIC_STRING_TO_FIXED_UL = "toFixed"
LIT_MAGIC_STRING_TRIM_END = "trimEnd"
LIT_MAGIC_STRING_UNICODE = "unicode"
LIT_MAGIC_STRING_UNSHIFT = "unshift"
LIT_MAGIC_STRING_VALUE_OF_UL = "valueOf"
@ -236,6 +237,7 @@ LIT_MAGIC_STRING_SET_MONTH_UL = "setMonth"
LIT_MAGIC_STRING_SET_UINT8_UL = "setUint8"
LIT_MAGIC_STRING_SUBARRAY = "subarray"
LIT_MAGIC_STRING_TO_STRING_UL = "toString"
LIT_MAGIC_STRING_TRIM_LEFT = "trimLeft"
LIT_MAGIC_STRING_UNESCAPE = "unescape"
LIT_MAGIC_STRING_WRITABLE = "writable"
LIT_MAGIC_STRING_OBJECT_TO_STRING_UL = "[object "
@ -267,6 +269,8 @@ LIT_MAGIC_STRING_STRINGIFY = "stringify"
LIT_MAGIC_STRING_SET_UINT16_UL = "setUint16"
LIT_MAGIC_STRING_SET_UINT32_UL = "setUint32"
LIT_MAGIC_STRING_SUBSTRING = "substring"
LIT_MAGIC_STRING_TRIM_RIGHT = "trimRight"
LIT_MAGIC_STRING_TRIM_START = "trimStart"
LIT_MAGIC_STRING_UNDEFINED = "undefined"
LIT_MAGIC_STRING_INT16_ARRAY_UL = "Int16Array"
LIT_MAGIC_STRING_INT32_ARRAY_UL = "Int32Array"

View File

@ -0,0 +1,29 @@
// Copyright JS Foundation and other contributors, http://js.foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
var test = " asd ";
assert(test.trimStart() === "asd ")
assert(test.trimStart().length === 5)
assert(test.trimLeft() === "asd ")
assert(test.trimLeft().length === 5)
assert(String.prototype.trimStart === String.prototype.trimLeft)
assert(test.trimEnd() === " asd")
assert(test.trimEnd().length === 5)
assert(test.trimRight() === " asd")
assert(test.trimRight().length === 5)
assert(String.prototype.trimEnd === String.prototype.trimRight)
assert(test.trim() === "asd")
assert(test.trim().length === 3)

View File

@ -92,12 +92,6 @@
<test id="annexB/built-ins/String/prototype/sup/name.js"><reason></reason></test>
<test id="annexB/built-ins/String/prototype/sup/prop-desc.js"><reason></reason></test>
<test id="annexB/built-ins/String/prototype/sup/this-val-tostring-err.js"><reason></reason></test>
<test id="annexB/built-ins/String/prototype/trimLeft/length.js"><reason></reason></test>
<test id="annexB/built-ins/String/prototype/trimLeft/name.js"><reason></reason></test>
<test id="annexB/built-ins/String/prototype/trimLeft/prop-desc.js"><reason></reason></test>
<test id="annexB/built-ins/String/prototype/trimRight/length.js"><reason></reason></test>
<test id="annexB/built-ins/String/prototype/trimRight/name.js"><reason></reason></test>
<test id="annexB/built-ins/String/prototype/trimRight/prop-desc.js"><reason></reason></test>
<test id="annexB/built-ins/TypedArrayConstructors/from/iterator-method-emulates-undefined.js"><reason></reason></test>
<test id="annexB/built-ins/unescape/four-ignore-bad-u.js"><reason></reason></test>
<test id="annexB/built-ins/unescape/four.js"><reason></reason></test>
@ -1947,50 +1941,6 @@
<test id="built-ins/String/prototype/toLowerCase/Final_Sigma_U180E.js"><reason></reason></test>
<test id="built-ins/String/prototype/toLowerCase/special_casing_conditional.js"><reason></reason></test>
<test id="built-ins/String/prototype/toString/non-generic-realm.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/length.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/name.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/prop-desc.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-boolean.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-line-terminator.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-not-obj-coercible.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-number.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-cannot-convert-to-primitive-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-toprimitive-call-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-toprimitive-meth-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-toprimitive-meth-priority.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-toprimitive-returns-object-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-tostring-call-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-tostring-meth-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-tostring-meth-priority.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-tostring-returns-object-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-valueof-call-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-valueof-meth-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-valueof-meth-priority.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-object-valueof-returns-object-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-symbol-typeerror.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimEnd/this-value-whitespace.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/length.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/name.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/prop-desc.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-boolean.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-line-terminator.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-not-obj-coercible.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-number.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-cannot-convert-to-primitive-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-toprimitive-call-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-toprimitive-meth-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-toprimitive-meth-priority.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-toprimitive-returns-object-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-tostring-call-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-tostring-meth-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-tostring-meth-priority.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-tostring-returns-object-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-valueof-call-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-valueof-meth-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-valueof-meth-priority.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-object-valueof-returns-object-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-symbol-typeerror.js"><reason></reason></test>
<test id="built-ins/String/prototype/trimStart/this-value-whitespace.js"><reason></reason></test>
<test id="built-ins/String/prototype/valueOf/non-generic-realm.js"><reason></reason></test>
<test id="built-ins/String/symbol-string-coercion.js"><reason></reason></test>
<test id="built-ins/Symbol/asyncIterator/cross-realm.js"><reason></reason></test>