Fix sticky flag handling in @@replace (#4005)

JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai daniel.batyai@h-lab.eu
This commit is contained in:
Dániel Bátyai
2020-07-20 12:54:06 +02:00
committed by GitHub
parent c2bfdde806
commit 74781c28c2
6 changed files with 182 additions and 104 deletions
@@ -76,7 +76,7 @@ typedef struct
const lit_utf8_byte_t *matched_p; /**< matched string */ const lit_utf8_byte_t *matched_p; /**< matched string */
lit_utf8_size_t matched_size; /**< matcehd string size */ lit_utf8_size_t matched_size; /**< matcehd string size */
lit_utf8_size_t match_byte_pos; /**< byte position of the match in the source string */ lit_utf8_size_t match_byte_pos; /**< byte position of the match in the source string */
ecma_length_t index; /**< current match index */ uint16_t flags; /**< replace flags */
/** /**
* Capture results * Capture results
+120 -85
View File
@@ -2525,10 +2525,13 @@ cleanup_string:
*/ */
static ecma_value_t static ecma_value_t
ecma_regexp_replace_helper_fast (ecma_replace_context_t *ctx_p, /**<replace context */ ecma_regexp_replace_helper_fast (ecma_replace_context_t *ctx_p, /**<replace context */
const re_compiled_code_t *bc_p, /**< regexp bytecode */ ecma_extended_object_t *re_obj_p, /**< regexp object */
ecma_string_t *string_p, /**< source string */ ecma_string_t *string_p, /**< source string */
ecma_value_t replace_arg) /**< replace argument */ ecma_value_t replace_arg) /**< replace argument */
{ {
const re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
re_obj_p->u.class_prop.u.value);
JERRY_ASSERT (bc_p != NULL); JERRY_ASSERT (bc_p != NULL);
ecma_value_t result = ECMA_VALUE_EMPTY; ecma_value_t result = ECMA_VALUE_EMPTY;
@@ -2545,26 +2548,7 @@ ecma_regexp_replace_helper_fast (ecma_replace_context_t *ctx_p, /**<replace cont
const lit_utf8_byte_t *matched_p = NULL; const lit_utf8_byte_t *matched_p = NULL;
const lit_utf8_byte_t *current_p = ctx_p->string_p; const lit_utf8_byte_t *current_p = ctx_p->string_p;
const lit_utf8_byte_t *last_append_p = current_p; const lit_utf8_byte_t *last_append_p = current_p;
JERRY_ASSERT (ctx_p->index <= string_length); ecma_length_t index;
#if ENABLED (JERRY_ESNEXT)
/* Global matches always start at index 0, but Sticky matches may have a non-zero lastIndex. */
if (ctx_p->index > 0)
{
if (string_flags & ECMA_STRING_FLAG_IS_ASCII)
{
current_p += ctx_p->index;
}
else
{
ecma_length_t index = ctx_p->index;
while (index--)
{
lit_utf8_incr (&current_p);
}
}
}
#endif /* ENABLED (JERRY_ESNEXT) */
ecma_regexp_ctx_t re_ctx; ecma_regexp_ctx_t re_ctx;
ecma_regexp_initialize_context (&re_ctx, ecma_regexp_initialize_context (&re_ctx,
@@ -2572,6 +2556,57 @@ ecma_regexp_replace_helper_fast (ecma_replace_context_t *ctx_p, /**<replace cont
ctx_p->string_p, ctx_p->string_p,
string_end_p); string_end_p);
/* lastIndex must be accessed to remain consistent with the standard, even though we may not need the value. */
ecma_value_t lastindex_value = ecma_op_object_get_by_magic_id ((ecma_object_t *) re_obj_p,
LIT_MAGIC_STRING_LASTINDEX_UL);
result = ecma_op_to_length (lastindex_value, &index);
ecma_free_value (lastindex_value);
if (ECMA_IS_VALUE_ERROR (result))
{
goto cleanup_context;
}
#if ENABLED (JERRY_ESNEXT)
/* Only non-global sticky matches use the lastIndex value, otherwise the starting index is 0. */
if (JERRY_UNLIKELY ((ctx_p->flags & RE_FLAG_GLOBAL) == 0 && (re_ctx.flags & RE_FLAG_STICKY) != 0))
{
if (index > string_length)
{
result = ecma_op_object_put ((ecma_object_t *) re_obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
ecma_make_uint32_value (0),
true);
if (!ECMA_IS_VALUE_ERROR (result))
{
JERRY_ASSERT (ecma_is_value_true (result));
ecma_ref_ecma_string (string_p);
result = ecma_make_string_value (string_p);
}
goto cleanup_context;
}
if (string_flags & ECMA_STRING_FLAG_IS_ASCII)
{
current_p += index;
}
else
{
ecma_length_t counter = index;
while (counter--)
{
lit_utf8_incr (&current_p);
}
}
}
else
#endif /* ENABLED (JERRY_ESNEXT) */
{
index = 0;
}
ctx_p->builder = ecma_stringbuilder_create (); ctx_p->builder = ecma_stringbuilder_create ();
ctx_p->capture_count = re_ctx.captures_count; ctx_p->capture_count = re_ctx.captures_count;
ctx_p->u.captures_p = re_ctx.captures_p; ctx_p->u.captures_p = re_ctx.captures_p;
@@ -2610,7 +2645,7 @@ ecma_regexp_replace_helper_fast (ecma_replace_context_t *ctx_p, /**<replace cont
ecma_collection_push_back (arguments_p, capture); ecma_collection_push_back (arguments_p, capture);
} }
ecma_collection_push_back (arguments_p, ecma_make_uint32_value (ctx_p->index)); ecma_collection_push_back (arguments_p, ecma_make_uint32_value (index));
ecma_ref_ecma_string (string_p); ecma_ref_ecma_string (string_p);
ecma_collection_push_back (arguments_p, ecma_make_string_value (string_p)); ecma_collection_push_back (arguments_p, ecma_make_string_value (string_p));
ecma_object_t *function_p = ecma_get_object_from_value (replace_arg); ecma_object_t *function_p = ecma_get_object_from_value (replace_arg);
@@ -2644,19 +2679,53 @@ ecma_regexp_replace_helper_fast (ecma_replace_context_t *ctx_p, /**<replace cont
const ecma_regexp_capture_t *global_capture_p = re_ctx.captures_p; const ecma_regexp_capture_t *global_capture_p = re_ctx.captures_p;
last_append_p = global_capture_p->end_p; last_append_p = global_capture_p->end_p;
if (!(re_ctx.flags & RE_FLAG_GLOBAL)) const lit_utf8_size_t matched_size = (lit_utf8_size_t) (global_capture_p->end_p - global_capture_p->begin_p);
const bool is_ascii = (string_flags & ECMA_STRING_FLAG_IS_ASCII) != 0;
index += is_ascii ? matched_size : lit_utf8_string_length (current_p, matched_size);
if (!(ctx_p->flags & RE_FLAG_GLOBAL))
{ {
#if ENABLED (JERRY_ESNEXT)
if (JERRY_UNLIKELY ((re_ctx.flags & RE_FLAG_STICKY) != 0))
{
result = ecma_op_object_put ((ecma_object_t *) re_obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
ecma_make_uint32_value (index),
true);
if (ECMA_IS_VALUE_ERROR (result))
{
goto cleanup_builder;
}
}
#endif /* ENABLED (JERRY_ESNEXT) */
break; break;
} }
const lit_utf8_size_t matched_size = (lit_utf8_size_t) (global_capture_p->end_p - global_capture_p->begin_p);
if (matched_size > 0) if (matched_size > 0)
{ {
ctx_p->index += lit_utf8_string_length (current_p, matched_size);
current_p = last_append_p; current_p = last_append_p;
continue; continue;
} }
} }
#if ENABLED (JERRY_ESNEXT)
else if (JERRY_UNLIKELY ((re_ctx.flags & RE_FLAG_STICKY) != 0))
{
result = ecma_op_object_put ((ecma_object_t *) re_obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
ecma_make_uint32_value (0),
true);
if (ECMA_IS_VALUE_ERROR (result))
{
goto cleanup_builder;
}
break;
}
#endif /* ENABLED (JERRY_ESNEXT) */
if (current_p >= string_end_p) if (current_p >= string_end_p)
{ {
@@ -2664,22 +2733,22 @@ ecma_regexp_replace_helper_fast (ecma_replace_context_t *ctx_p, /**<replace cont
} }
#if ENABLED (JERRY_ESNEXT) #if ENABLED (JERRY_ESNEXT)
if ((re_ctx.flags & RE_FLAG_UNICODE) != 0) if ((ctx_p->flags & RE_FLAG_UNICODE) != 0)
{ {
ctx_p->index++; index++;
const lit_code_point_t cp = ecma_regexp_unicode_advance (&current_p, const lit_code_point_t cp = ecma_regexp_unicode_advance (&current_p,
string_end_p); string_end_p);
if (cp > LIT_UTF16_CODE_UNIT_MAX) if (cp > LIT_UTF16_CODE_UNIT_MAX)
{ {
ctx_p->index++; index++;
} }
continue; continue;
} }
#endif /* ENABLED (JERRY_ESNEXT) */ #endif /* ENABLED (JERRY_ESNEXT) */
ctx_p->index++; index++;
lit_utf8_incr (&current_p); lit_utf8_incr (&current_p);
} }
@@ -2727,7 +2796,7 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
ecma_object_t *this_obj_p = ecma_get_object_from_value (this_arg); ecma_object_t *this_obj_p = ecma_get_object_from_value (this_arg);
ecma_replace_context_t replace_ctx; ecma_replace_context_t replace_ctx;
replace_ctx.index = 0; replace_ctx.flags = RE_FLAG_EMPTY;
/* 3. */ /* 3. */
ecma_string_t *string_p = ecma_op_to_string (string_arg); ecma_string_t *string_p = ecma_op_to_string (string_arg);
@@ -2757,16 +2826,19 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
goto cleanup_replace; goto cleanup_replace;
} }
const bool global = ecma_op_to_boolean (result); if (ecma_op_to_boolean (result))
{
replace_ctx.flags |= RE_FLAG_GLOBAL;
}
ecma_free_value (result); ecma_free_value (result);
#if ENABLED (JERRY_ESNEXT) #if ENABLED (JERRY_ESNEXT)
const lit_utf8_size_t string_length = ecma_string_get_length (string_p); const lit_utf8_size_t string_length = ecma_string_get_length (string_p);
bool unicode = false;
#endif /* ENABLED (JERRY_ESNEXT) */ #endif /* ENABLED (JERRY_ESNEXT) */
/* 10. */ /* 10. */
if (global) if (replace_ctx.flags & RE_FLAG_GLOBAL)
{ {
#if ENABLED (JERRY_ESNEXT) #if ENABLED (JERRY_ESNEXT)
result = ecma_op_object_get_by_magic_id (this_obj_p, LIT_MAGIC_STRING_UNICODE); result = ecma_op_object_get_by_magic_id (this_obj_p, LIT_MAGIC_STRING_UNICODE);
@@ -2775,7 +2847,11 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
goto cleanup_replace; goto cleanup_replace;
} }
unicode = ecma_op_to_boolean (result); if (ecma_op_to_boolean (result))
{
replace_ctx.flags |= RE_FLAG_UNICODE;
}
ecma_free_value (result); ecma_free_value (result);
#endif /* ENABLED (JERRY_ESNEXT) */ #endif /* ENABLED (JERRY_ESNEXT) */
@@ -2792,12 +2868,8 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
} }
#if !ENABLED (JERRY_ESNEXT) #if !ENABLED (JERRY_ESNEXT)
ecma_extended_object_t *re_obj_p = (ecma_extended_object_t *) this_obj_p;
const re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
re_obj_p->u.class_prop.u.value);
result = ecma_regexp_replace_helper_fast (&replace_ctx, result = ecma_regexp_replace_helper_fast (&replace_ctx,
bc_p, (ecma_extended_object_t *) this_obj_p,
string_p, string_p,
replace_arg); replace_arg);
@@ -2818,47 +2890,9 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
&& ecma_builtin_is_regexp_exec (function_p)) && ecma_builtin_is_regexp_exec (function_p))
{ {
ecma_deref_object ((ecma_object_t *) function_p); ecma_deref_object ((ecma_object_t *) function_p);
result = ecma_op_object_get_by_magic_id (this_obj_p, LIT_MAGIC_STRING_STICKY);
if (ECMA_IS_VALUE_ERROR (result))
{
goto cleanup_replace;
}
const bool sticky = ecma_op_to_boolean (result);
ecma_free_value (result);
if (sticky && !global)
{
ecma_value_t lastindex_value = ecma_op_object_get_by_magic_id (this_obj_p, LIT_MAGIC_STRING_LASTINDEX_UL);
result = ecma_op_to_length (lastindex_value, &replace_ctx.index);
ecma_free_value (lastindex_value);
if (ECMA_IS_VALUE_ERROR (result))
{
goto cleanup_replace;
}
if (replace_ctx.index > string_length)
{
result = ecma_op_object_put (this_obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
ecma_make_uint32_value (0),
true);
JERRY_ASSERT (ecma_is_value_true (result));
ecma_ref_ecma_string (string_p);
result = ecma_make_string_value (string_p);
goto cleanup_replace;
}
}
ecma_extended_object_t *re_obj_p = (ecma_extended_object_t *) this_obj_p;
const re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t,
re_obj_p->u.class_prop.u.value);
result = ecma_regexp_replace_helper_fast (&replace_ctx, result = ecma_regexp_replace_helper_fast (&replace_ctx,
bc_p, (ecma_extended_object_t *) this_obj_p,
string_p, string_p,
replace_arg); replace_arg);
@@ -2914,7 +2948,7 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
/* 13.d.i */ /* 13.d.i */
ecma_collection_push_back (results_p, result); ecma_collection_push_back (results_p, result);
if (!global) if ((replace_ctx.flags & RE_FLAG_GLOBAL) == 0)
{ {
break; break;
} }
@@ -2957,7 +2991,7 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
ecma_free_value (result); ecma_free_value (result);
index = ecma_op_advance_string_index (string_p, index, unicode); index = ecma_op_advance_string_index (string_p, index, (replace_ctx.flags & RE_FLAG_UNICODE) != 0);
/* 10.d.iii.3.c */ /* 10.d.iii.3.c */
result = ecma_op_object_put (this_obj_p, result = ecma_op_object_put (this_obj_p,
@@ -2992,6 +3026,7 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
replace_ctx.builder = ecma_stringbuilder_create (); replace_ctx.builder = ecma_stringbuilder_create ();
replace_ctx.matched_p = NULL; replace_ctx.matched_p = NULL;
replace_ctx.capture_count = 0; replace_ctx.capture_count = 0;
ecma_length_t index = 0;
/* 15. */ /* 15. */
const lit_utf8_byte_t *source_position_p = replace_ctx.string_p; const lit_utf8_byte_t *source_position_p = replace_ctx.string_p;
@@ -3053,7 +3088,7 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
} }
/* 16.i */ /* 16.i */
lit_utf8_size_t position = JERRY_MIN ((lit_utf8_size_t) JERRY_MAX (position_num, 0.0f), string_length); ecma_length_t position = JERRY_MIN ((ecma_length_t) JERRY_MAX (position_num, 0.0f), string_length);
/* 16.k */ /* 16.k */
ecma_collection_t *arguments_p = ecma_new_collection (); ecma_collection_t *arguments_p = ecma_new_collection ();
@@ -3091,7 +3126,7 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
n++; n++;
} }
const bool should_replace = (position >= replace_ctx.index); const bool should_replace = (position >= index);
/* 16.p */ /* 16.p */
if (should_replace) if (should_replace)
{ {
@@ -3106,7 +3141,7 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
else else
{ {
match_position_p = source_position_p; match_position_p = source_position_p;
lit_utf8_size_t distance = position - replace_ctx.index; lit_utf8_size_t distance = position - index;
while (distance--) while (distance--)
{ {
lit_utf8_incr (&match_position_p); lit_utf8_incr (&match_position_p);
@@ -3134,7 +3169,7 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
source_position_p = match_position_p; source_position_p = match_position_p;
} }
replace_ctx.index = JERRY_MIN (position + matched_str_length, string_length); index = JERRY_MIN (position + matched_str_length, string_length);
} }
/* 16.m */ /* 16.m */
@@ -3192,7 +3227,7 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
} }
/* 18. */ /* 18. */
JERRY_ASSERT (replace_ctx.index <= string_length); JERRY_ASSERT (index <= string_length);
ecma_stringbuilder_append_raw (&(replace_ctx.builder), ecma_stringbuilder_append_raw (&(replace_ctx.builder),
source_position_p, source_position_p,
(lit_utf8_size_t) (string_end_p - source_position_p)); (lit_utf8_size_t) (string_end_p - source_position_p));
+1 -2
View File
@@ -397,8 +397,7 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SOURCE, "source")
#if ENABLED (JERRY_BUILTIN_ARRAY) #if ENABLED (JERRY_BUILTIN_ARRAY)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SPLICE, "splice") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SPLICE, "splice")
#endif #endif
#if ENABLED (JERRY_BUILTIN_REGEXP) && ENABLED (JERRY_ESNEXT) \ #if ENABLED (JERRY_BUILTIN_REGEXP) && ENABLED (JERRY_ESNEXT)
|| ENABLED (JERRY_BUILTIN_REGEXP) && !( !ENABLED (JERRY_ESNEXT))
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_STICKY, "sticky") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_STICKY, "sticky")
#endif #endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_STRING, "string") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_STRING, "string")
+38 -2
View File
@@ -680,9 +680,45 @@ Object.defineProperty(abruptStickyRegexp, 'sticky', {
} }
}); });
assert(abruptStickyRegexp[Symbol.replace]() === "undefinedndefined");
var r = /./;
r.lastIndex = {
valueOf: function() {
throw "abrupt lastIndex"
}
}
try { try {
abruptStickyRegexp[Symbol.replace](); r[Symbol.replace]("a", "b");
assert(false); assert(false);
} catch (e) { } catch (e) {
assert(e === "abrupt sticky"); assert(e === "abrupt lastIndex");
} }
var r = /a/y;
r.lastIndex = 3;
assert (r[Symbol.replace]("aaaaa", "b") === "aaaba");
assert (r.lastIndex === 4);
assert (r[Symbol.replace]("ccccc", "b") === "ccccc");
assert (r.lastIndex === 0);
var r = /a/yg;
r.lastIndex = 3;
assert (r[Symbol.replace]("aaaaa", "b") === "bbbbb");
assert (r.lastIndex === 0);
var replaceCalled = false;
var r = /a/
r.lastIndex = 2;
assert(r[Symbol.replace]("aaaa", function(match, index) {
replaceCalled = true;
assert (match === "a");
assert (index === 0);
return "b";
}) === "baaa");
assert (replaceCalled);
assert (r.lastIndex === 2)
+14
View File
@@ -132,3 +132,17 @@ try {
} catch (e) { } catch (e) {
assert (e === "abrupt replacer toString"); assert (e === "abrupt replacer toString");
} }
var r = /./;
r.lastIndex = {
valueOf: function() {
throw "abrupt lastIndex"
}
}
try {
"a".replace(r, "b");
assert(false);
} catch (e) {
assert(e === "abrupt lastIndex");
}
+8 -14
View File
@@ -80,8 +80,8 @@
<test id="built-ins/Reflect/enumerate/name.js"><reason></reason></test> <test id="built-ins/Reflect/enumerate/name.js"><reason></reason></test>
<test id="built-ins/Reflect/enumerate/return-abrupt-from-result.js"><reason></reason></test> <test id="built-ins/Reflect/enumerate/return-abrupt-from-result.js"><reason></reason></test>
<test id="built-ins/Reflect/enumerate/return-iterator.js"><reason></reason></test> <test id="built-ins/Reflect/enumerate/return-iterator.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/exec/get-sticky-coerce.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/exec/get-sticky-coerce.js"><reason>RegExpBuiltinExec no longer uses accessors to get flags</reason></test>
<test id="built-ins/RegExp/prototype/exec/get-sticky-err.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/exec/get-sticky-err.js"><reason>RegExpBuiltinExec no longer uses accessors to get flags</reason></test>
<test id="built-ins/RegExp/prototype/Symbol.match/builtin-coerce-global.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.match/builtin-coerce-global.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.match/builtin-coerce-lastindex-err.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.match/builtin-coerce-lastindex-err.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.match/builtin-coerce-sticky.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.match/builtin-coerce-sticky.js"><reason></reason></test>
@@ -92,18 +92,12 @@
<test id="built-ins/RegExp/prototype/Symbol.match/builtin-success-g-set-lastindex-err.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.match/builtin-success-g-set-lastindex-err.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.match/builtin-success-g-set-lastindex.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.match/builtin-success-g-set-lastindex.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.match/coerce-global.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.match/coerce-global.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.match/coerce-sticky.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.match/coerce-sticky.js"><reason>RegExpBuiltinExec no longer uses accessors to get flags</reason></test>
<test id="built-ins/RegExp/prototype/Symbol.match/get-sticky-err.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.match/get-sticky-err.js"><reason>RegExpBuiltinExec no longer uses accessors to get flags</reason></test>
<test id="built-ins/RegExp/prototype/Symbol.replace/coerce-global.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.replace/get-sticky-coerce.js"><reason>RegExpBuiltinExec no longer uses accessors to get flags</reason></test>
<test id="built-ins/RegExp/prototype/Symbol.replace/coerce-unicode.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.replace/get-sticky-err.js"><reason>RegExpBuiltinExec no longer uses accessors to get flags</reason></test>
<test id="built-ins/RegExp/prototype/Symbol.replace/get-sticky-coerce.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.search/get-sticky-coerce.js"><reason>RegExpBuiltinExec no longer uses accessors to get flags</reason></test>
<test id="built-ins/RegExp/prototype/Symbol.replace/y-fail-global-return.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/Symbol.search/get-sticky-err.js"><reason>RegExpBuiltinExec no longer uses accessors to get flags</reason></test>
<test id="built-ins/RegExp/prototype/Symbol.replace/y-fail-lastindex.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.replace/y-fail-lastindex-no-write.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.replace/y-fail-return.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.replace/y-set-lastindex.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.search/get-sticky-coerce.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.search/get-sticky-err.js"><reason></reason></test>
<test id="built-ins/RegExp/prototype/Symbol.split/coerce-limit.js"><reason>Test is outdated: ES11, 21.2.5.13 13</reason></test> <test id="built-ins/RegExp/prototype/Symbol.split/coerce-limit.js"><reason>Test is outdated: ES11, 21.2.5.13 13</reason></test>
<test id="built-ins/RegExp/prototype/test/get-sticky-err.js"><reason></reason></test> <test id="built-ins/RegExp/prototype/test/get-sticky-err.js"><reason></reason></test>
<test id="built-ins/String/prototype/normalize/form-is-not-valid-throws.js"><reason></reason></test> <test id="built-ins/String/prototype/normalize/form-is-not-valid-throws.js"><reason></reason></test>