30using namespace regexp_compiler_constants;
43 uint32_t backtrack_limit);
63 int32_t* result_offsets_vector,
64 int result_offsets_vector_length);
68 int result_offsets_vector_length,
74 int32_t* result_offsets_vector,
75 int result_offsets_vector_length);
86 int32_t* output,
int output_size);
93 uint32_t result_offsets_vector_length);
108 uint32_t& backtrack_limit);
118 if (IsUnicode(flags) && IsUnicodeSets(flags))
return false;
123template <
class CharT>
130 zone, stack_limit, input, input_length, flags, &data, no_gc);
131 *regexp_error_out = data.error;
132 return pattern_is_valid;
139template bool RegExp::VerifySyntax<base::uc16>(
154 THROW_NEW_ERROR(isolate, NewSyntaxError(MessageTemplate::kMalformedRegExp,
155 pattern, flag_string, error_text));
178 const int kMod = 128;
179 bool character_found[kMod];
180 uint32_t different = 0;
181 memset(&character_found[0], 0,
sizeof(character_found));
183 int ch = (
pattern->Get(
i) & (kMod - 1));
184 if (!character_found[ch]) {
185 character_found[ch] =
true;
189 if (different * 3 > length)
return false;
204 uint32_t backtrack_limit) {
210 const bool is_compilation_cache_enabled =
215 if (is_compilation_cache_enabled) {
216 compilation_cache = isolate->compilation_cache();
221 if (maybe_cached.
ToHandle(&cached)) {
222 re->set_data(*cached);
229 DCHECK(!isolate->has_exception());
237 bool has_been_compiled =
false;
239 if (
v8_flags.default_to_experimental_regexp_engine &&
245 has_been_compiled =
true;
246 }
else if (flags & JSRegExp::kLinear) {
253 RegExpError::kNotLinear);
257 has_been_compiled =
true;
258 }
else if (parse_result.
simple && !IsIgnoreCase(flags) && !IsSticky(flags) &&
259 !HasFewDifferentCharacters(
pattern)) {
262 has_been_compiled =
true;
263 }
else if (parse_result.
tree->IsAtom() && !IsSticky(flags) &&
271 isolate, atom_string,
272 isolate->factory()->NewStringFromTwoByte(atom_pattern));
273 if (!IsIgnoreCase(flags) && !HasFewDifferentCharacters(atom_string)) {
275 has_been_compiled =
true;
278 if (!has_been_compiled) {
285 if (is_compilation_cache_enabled) {
297 switch (re_data->type_tag()) {
303 DCHECK(isolate->has_exception());
311 DCHECK(isolate->has_exception());
323 uint32_t result_offsets_vector_length) {
327 subject, index, result_offsets_vector,
328 result_offsets_vector_length);
334 int32_t* result_offsets_vector,
335 uint32_t result_offsets_vector_length) {
337 switch (data->type_tag()) {
340 index, result_offsets_vector,
341 result_offsets_vector_length);
344 subject, index, result_offsets_vector,
345 result_offsets_vector_length);
348 subject, index, result_offsets_vector,
349 result_offsets_vector_length);
364 int capture_count = data->capture_count();
365 int result_offsets_vector_length =
368 result_offsets_vector_length);
369 std::optional<int>
result =
371 result_offsets_vector_length);
375 if (
result.value() == 0) {
376 return isolate->factory()->null_value();
381 capture_count, result_vector_scope.
value());
389 isolate->factory()->SetRegExpAtomData(
395template <
typename SChar,
typename PChar>
398 RegExpFlags flags, int32_t* output,
int output_size,
400 const int subject_length = subject.
length();
401 const int pattern_length =
pattern.length();
403 const int max_index = subject_length - pattern_length;
407 if constexpr (std::is_same_v<SChar, uint16_t>) {
408 if (index > 0 && index < subject_length &&
419 if (index > max_index) {
423 index = search.Search(subject, index);
429 index += pattern_length;
443 int32_t* result_offsets_vector,
444 int result_offsets_vector_length) {
452 return AtomExecRaw(isolate, needle_content, subject_content, index, flags,
453 result_offsets_vector, result_offsets_vector_length,
462 int result_offsets_vector_length,
473 pattern.ToOneByteVector(), index, flags,
474 result_offsets_vector,
475 result_offsets_vector_length, no_gc)
477 pattern.ToOneByteVector(), index, flags,
478 result_offsets_vector,
479 result_offsets_vector_length, no_gc))
482 pattern.ToUC16Vector(), index, flags,
483 result_offsets_vector,
484 result_offsets_vector_length, no_gc)
486 pattern.ToUC16Vector(), index, flags,
487 result_offsets_vector,
488 result_offsets_vector_length, no_gc));
495 int32_t index, int32_t* result_offsets_vector,
496 int32_t result_offsets_vector_length) {
508 index, flags, result_offsets_vector,
509 result_offsets_vector_length, no_gc);
514 int32_t* result_offsets_vector,
515 int result_offsets_vector_length) {
516 int res =
AtomExecRaw(isolate, re_data, subject, index, result_offsets_vector,
517 result_offsets_vector_length);
535 bool has_bytecode = re_data->has_bytecode(is_one_byte);
536 bool needs_initial_compilation = !re_data->has_code(is_one_byte);
540 bool needs_tier_up_compilation = re_data->MarkedForTierUp() && has_bytecode;
542 if (
v8_flags.trace_regexp_tier_up && needs_tier_up_compilation) {
543 PrintF(
"JSRegExp object (data: %p) needs tier-up compilation\n",
544 reinterpret_cast<void*
>(re_data->ptr()));
547 if (!needs_initial_compilation && !needs_tier_up_compilation) {
548 DCHECK(re_data->has_code(is_one_byte));
564 bool has_code = re_data->has_code(is_one_byte);
565 bool has_bytecode = re_data->has_bytecode(is_one_byte);
566 if (re_data->ShouldProduceBytecode()) {
577struct RegExpCaptureIndexLess {
578 bool operator()(
const RegExpCapture* lhs,
const RegExpCapture* rhs)
const {
581 return lhs->index() < rhs->index();
597 std::sort(named_captures->
begin(), named_captures->
end(),
598 RegExpCaptureIndexLess{});
600 int len =
static_cast<int>(named_captures->
size()) * 2;
606 capture->name()->size());
610 isolate->factory()->InternalizeString(capture_name);
611 array->set(
i * 2, *name);
630 if (
v8_flags.correctness_fuzzer_suppressions) {
631 FATAL(
"Aborting on stack overflow");
634 RegExpError::kAnalysisStackOverflow);
642 DCHECK(RegExpCodeIsValidForPreCompilation(isolate, re_data, is_one_byte));
654 compile_data.
error));
665 uint32_t backtrack_limit = re_data->backtrack_limit();
666 const bool compilation_succeeded =
667 Compile(isolate, &zone, &compile_data, flags,
pattern, sample_subject,
668 is_one_byte, backtrack_limit);
669 if (!compilation_succeeded) {
680 re_data->clear_bytecode(is_one_byte);
686 re_data->set_bytecode(is_one_byte,
690 re_data->set_code(is_one_byte, *trampoline);
695 int register_max = re_data->max_register_count();
699 re_data->set_backtrack_limit(backtrack_limit);
701 if (
v8_flags.trace_regexp_tier_up) {
702 PrintF(
"JSRegExp data object %p %s size: %d\n",
703 reinterpret_cast<void*
>(re_data->ptr()),
704 re_data->ShouldProduceBytecode() ?
"bytecode" :
"native code",
705 re_data->ShouldProduceBytecode()
706 ? re_data->bytecode(is_one_byte)->AllocatedSize()
707 : re_data->code(isolate, is_one_byte)->Size());
716 uint32_t backtrack_limit) {
718 isolate->factory()->SetRegExpIrregexpData(re,
pattern,
720 capture_count, backtrack_limit);
727 DCHECK(subject->IsFlat());
744 int32_t* output,
int output_size) {
747 DCHECK(subject->IsFlat());
753 if (!regexp_data->ShouldProduceBytecode()) {
761 output_size, index, isolate);
764 isolate->has_exception());
783 DCHECK(regexp_data->ShouldProduceBytecode());
787 isolate, regexp_data, subject, output, output_size, index);
789 isolate->has_exception());
803 if (
v8_flags.regexp_tier_up) regexp_data->ResetLastTierUpTick();
819 int32_t* result_offsets_vector, uint32_t result_offsets_vector_length) {
823 if (
v8_flags.trace_regexp_bytecodes && regexp_data->ShouldProduceBytecode()) {
824 PrintF(
"\n\nRegexp match: /%s/\n\n",
825 regexp_data->source()->ToCString().get());
826 PrintF(
"\n\nSubject string: '%s'\n\n", subject->ToCString().get());
830 const int original_register_count =
841 regexp_data->MarkTierUpForNextExec();
842 if (
v8_flags.trace_regexp_tier_up) {
844 "Forcing tier-up for very long strings in "
845 "RegExpImpl::IrregexpExec\n");
847 }
else if (
static_cast<uint32_t
>(original_register_count) <
848 result_offsets_vector_length) {
851 if (
v8_flags.trace_regexp_tier_up) {
853 "Forcing tier-up of RegExpData object %p for global irregexp "
855 reinterpret_cast<void*
>(regexp_data->ptr()));
860 int output_register_count =
862 if (output_register_count < 0) {
863 DCHECK(isolate->has_exception());
869 CHECK_EQ(original_register_count, output_register_count);
870 CHECK_LE(
static_cast<uint32_t
>(output_register_count),
871 result_offsets_vector_length);
876 previous_index, result_offsets_vector,
877 result_offsets_vector_length);
880 DCHECK_LE(res * output_register_count, result_offsets_vector_length);
884 isolate, regexp_data, subject, previous_index, result_offsets_vector,
885 result_offsets_vector_length);
887 DCHECK(isolate->has_exception());
901 if (*
result != *last_match_info) {
902 if (*last_match_info == *isolate->regexp_last_match_info()) {
907 isolate->native_context()->set_regexp_last_match_info(*
result);
911 int capture_register_count =
914 if (match !=
nullptr) {
915 for (
int i = 0;
i < capture_register_count;
i += 2) {
917 result->set_capture(
i + 1, match[
i + 1]);
920 result->set_last_subject(*subject);
921 result->set_last_input(*subject);
940 static constexpr size_t kRegExpExecutableMemoryLimit = 16 *
MB;
941 static constexpr size_t kRegExpCompiledLimit = 1 *
MB;
945 return (isolate->total_regexp_code_generated() > kRegExpCompiledLimit &&
946 heap->CommittedMemoryExecutable() > kRegExpExecutableMemoryLimit);
959 sample_subject, is_one_byte, backtrack_limit);
965 uint32_t& backtrack_limit) {
968 data->error = RegExpError::kTooLarge;
972 RegExpCompiler compiler(isolate, zone, data->capture_count, flags,
975 if (compiler.optimize()) {
976 compiler.set_optimize(!TooMuchRegExpCode(isolate,
pattern));
980 static const int kSampleSize = 128;
984 if (sample_subject->length() > kSampleSize) {
985 start = (sample_subject->length() - kSampleSize) / 2;
989 end = sample_subject->length();
992 compiler.frequency_collator()->CountCharacter(sample_subject->Get(
i));
995 data->node = compiler.PreprocessRegExp(data, is_one_byte);
996 if (data->error != RegExpError::kNone) {
999 data->error =
AnalyzeRegExp(isolate, is_one_byte, flags, data->node);
1000 if (data->error != RegExpError::kNone) {
1007 std::unique_ptr<RegExpMacroAssembler> macro_assembler;
1016 const int output_register_count =
1018#if V8_TARGET_ARCH_IA32
1020 output_register_count));
1021#elif V8_TARGET_ARCH_X64
1023 output_register_count));
1024#elif V8_TARGET_ARCH_ARM
1026 output_register_count));
1027#elif V8_TARGET_ARCH_ARM64
1029 output_register_count));
1030#elif V8_TARGET_ARCH_S390X
1032 output_register_count));
1033#elif V8_TARGET_ARCH_PPC64
1035 output_register_count));
1036#elif V8_TARGET_ARCH_MIPS64
1038 output_register_count));
1039#elif V8_TARGET_ARCH_RISCV64
1041 output_register_count));
1042#elif V8_TARGET_ARCH_RISCV32
1044 output_register_count));
1045#elif V8_TARGET_ARCH_LOONG64
1047 isolate, zone, mode, output_register_count));
1049#error "Unsupported architecture"
1057 macro_assembler->set_slow_safe(TooMuchRegExpCode(isolate,
pattern));
1058 if (
v8_flags.enable_experimental_regexp_engine_on_excessive_backtracks &&
1060 data->capture_count)) {
1062 backtrack_limit =
v8_flags.regexp_backtracks_before_fallback;
1064 backtrack_limit = std::min(
1065 backtrack_limit,
v8_flags.regexp_backtracks_before_fallback.value());
1067 macro_assembler->set_backtrack_limit(backtrack_limit);
1068 macro_assembler->set_can_fallback(
true);
1070 macro_assembler->set_backtrack_limit(backtrack_limit);
1071 macro_assembler->set_can_fallback(
false);
1076 bool is_end_anchored = data->tree->IsAnchoredAtEnd();
1077 bool is_start_anchored = data->tree->IsAnchoredAtStart();
1078 int max_length = data->tree->max_match();
1079 static const int kMaxBacksearchLimit = 1024;
1080 if (is_end_anchored && !is_start_anchored && !IsSticky(flags) &&
1081 max_length < kMaxBacksearchLimit) {
1082 macro_assembler->SetCurrentPositionFromEnd(max_length);
1085 if (IsGlobal(flags)) {
1087 if (data->tree->min_match() > 0) {
1092 macro_assembler->set_global_mode(mode);
1097 std::unique_ptr<RegExpMacroAssembler> tracer_macro_assembler;
1098 if (
v8_flags.trace_regexp_assembler) {
1099 tracer_macro_assembler.reset(
1101 macro_assembler_ptr = tracer_macro_assembler.get();
1106 isolate, macro_assembler_ptr, data->node, data->capture_count,
pattern);
1110#ifdef ENABLE_DISASSEMBLER
1116 std::unique_ptr<char[]> pattern_cstring =
pattern->ToCString();
1117 code->Disassemble(pattern_cstring.get(), os, isolate);
1120 if (
v8_flags.print_regexp_bytecode &&
1123 std::unique_ptr<char[]> pattern_cstring =
pattern->ToCString();
1125 pattern_cstring.get());
1129 if (
result.error != RegExpError::kNone) {
1130 if (
v8_flags.correctness_fuzzer_suppressions &&
1131 result.error == RegExpError::kStackOverflow) {
1132 FATAL(
"Aborting on stack overflow");
1134 data->error =
result.error;
1138 data->register_count =
result.num_registers;
1140 return result.Succeeded();
1146 : result_vector_scope_(isolate),
1147 regexp_data_(regexp_data),
1180 DCHECK(isolate->has_exception());
1202 int32_t* last_match =
1210 static_cast<uint32_t
>(last_index + 1) <
subject_->length() &&
1214 return last_index + 2;
1216 return last_index + 1;
1230 int32_t* last_match =
1232 int last_end_index = last_match[1];
1250 int last_start_index = last_match[0];
1251 if (last_start_index == last_end_index) {
1255 if (
static_cast<uint32_t
>(last_end_index) >
subject_->length()) {
1307 if (!IsInternalizedString(key_string))
return Smi::zero();
1309 DCHECK(IsString(key_pattern));
1310 if (!IsInternalizedString(key_pattern))
return Smi::zero();
1311 cache =
heap->string_split_cache();
1314 DCHECK(IsRegExpDataWrapper(key_pattern));
1315 cache =
heap->regexp_multiple_cache();
1318 uint32_t hash = key_string->hash();
1342 Factory* factory = isolate->factory();
1344 if (!IsInternalizedString(*key_string))
return;
1346 DCHECK(IsString(*key_pattern));
1347 if (!IsInternalizedString(*key_pattern))
return;
1348 cache = factory->string_split_cache();
1351 DCHECK(IsRegExpDataWrapper(*key_pattern));
1352 cache = factory->regexp_multiple_cache();
1355 uint32_t hash = key_string->hash();
1385 for (
int i = 0;
i < value_array->length();
i++) {
1388 value_array->set(
i, *internalized_str);
1392 value_array->set_map_no_write_barrier(
1406 int number_of_matches,
1407 int last_match_index) {
1411 if (!IsSlicedString(subject))
return;
1424 int* number_of_matches_out,
1425 int* last_match_index_out) {
1430 if (!IsSlicedString(subject))
return false;
1440 Clear(isolate->heap());
1444 if (cached_subject->parent() != sliced_subject->parent())
return false;
1445 if (cached_subject->offset() != sliced_subject->offset())
return false;
1446 if (cached_subject->length() > sliced_subject->length())
return false;
1454 MemsetTagged(
heap->regexp_match_global_atom_cache()->RawFieldOfFirstElement(),
1459#define V(Lower, Camel, LowerCamel, Char, Bit) \
1460 if (flags & RegExpFlag::k##Camel) os << Char;
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
#define BUILTIN_CODE(isolate, name)
#define SBXCHECK_LE(lhs, rhs)
#define SBXCHECK(condition)
static bool IsTrailSurrogate(int code)
static bool IsLeadSurrogate(int code)
void PutRegExp(DirectHandle< String > source, JSRegExp::Flags flags, DirectHandle< RegExpData > data)
MaybeDirectHandle< RegExpData > LookupRegExp(DirectHandle< String > source, JSRegExp::Flags flags)
static void DotPrint(const char *label, RegExpNode *node)
static int32_t ExecRaw(Isolate *isolate, RegExp::CallOrigin call_origin, Tagged< IrRegExpData > regexp_data, Tagged< String > subject, int32_t *output_registers, int32_t output_register_count, int32_t subject_index)
static void Initialize(Isolate *isolate, DirectHandle< JSRegExp > re, DirectHandle< String > pattern, RegExpFlags flags, int capture_count)
static bool CanBeHandled(RegExpTree *tree, DirectHandle< String > pattern, RegExpFlags flags, int capture_count)
static bool IsCompiled(DirectHandle< IrRegExpData > re_data, Isolate *isolate)
static V8_WARN_UNUSED_RESULT bool Compile(Isolate *isolate, DirectHandle< IrRegExpData > re_data)
static std::optional< int > Exec(Isolate *isolate, DirectHandle< IrRegExpData > regexp_data, DirectHandle< String > subject, int index, int32_t *result_offsets_vector, uint32_t result_offsets_vector_length)
static std::optional< int > OneshotExec(Isolate *isolate, DirectHandle< IrRegExpData > regexp_data, DirectHandle< String > subject, int index, int32_t *result_offsets_vector, uint32_t result_offsets_vector_length)
static int32_t OneshotExecRaw(Isolate *isolate, DirectHandle< IrRegExpData > regexp_data, DirectHandle< String > subject, int32_t *output_registers, int32_t output_register_count, int32_t subject_index)
Handle< String > InternalizeString(base::Vector< const char > str, bool convert_encoding=false)
static int MatchForCallFromRuntime(Isolate *isolate, DirectHandle< IrRegExpData > regexp_data, DirectHandle< String > subject_string, int *output_registers, int output_register_count, int start_position)
@ FALLBACK_TO_EXPERIMENTAL
static const int kJSRegexpStaticOffsetsVectorSize
static constexpr int kAtomRegisterCount
static constexpr RegExpFlags AsRegExpFlags(Flags f)
static constexpr uint32_t kNoBacktrackLimit
static V8_EXPORT_PRIVATE DirectHandle< String > StringFromFlags(Isolate *isolate, Flags flags)
static constexpr Flags AsJSRegExpFlags(RegExpFlags f)
static constexpr int RegistersForCaptureCount(int count)
static constexpr int kTierUpForSubjectLengthValue
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
static int Match(DirectHandle< IrRegExpData > regexp_data, DirectHandle< String > subject, int *offsets_vector, int offsets_vector_length, int previous_index, Isolate *isolate)
base::Vector< const base::uc16 > data() const
int32_t * LastSuccessfulMatch() const
RegExpGlobalExecRunner(DirectHandle< RegExpData > regexp_data, DirectHandle< String > subject, Isolate *isolate)
DirectHandle< String > subject_
DirectHandle< RegExpData > regexp_data_
int AdvanceZeroLength(int last_index) const
int32_t * register_array_
RegExpResultVectorScope result_vector_scope_
static int AtomExec(Isolate *isolate, DirectHandle< AtomRegExpData > regexp_data, DirectHandle< String > subject, int index, int32_t *result_offsets_vector, int result_offsets_vector_length)
static V8_WARN_UNUSED_RESULT std::optional< int > IrregexpExec(Isolate *isolate, DirectHandle< IrRegExpData > regexp_data, DirectHandle< String > subject, int index, int32_t *result_offsets_vector, uint32_t result_offsets_vector_length)
static int IrregexpPrepare(Isolate *isolate, DirectHandle< IrRegExpData > regexp_data, DirectHandle< String > subject)
static int AtomExecRaw(Isolate *isolate, DirectHandle< AtomRegExpData > regexp_data, DirectHandle< String > subject, int index, int32_t *result_offsets_vector, int result_offsets_vector_length)
static void AtomCompile(Isolate *isolate, DirectHandle< JSRegExp > re, DirectHandle< String > pattern, RegExpFlags flags, DirectHandle< String > match_pattern)
static bool EnsureCompiledIrregexp(Isolate *isolate, DirectHandle< IrRegExpData > re_data, DirectHandle< String > sample_subject, bool is_one_byte)
static void IrregexpInitialize(Isolate *isolate, DirectHandle< JSRegExp > re, DirectHandle< String > pattern, RegExpFlags flags, int capture_count, uint32_t backtrack_limit)
static int IrregexpExecRaw(Isolate *isolate, DirectHandle< IrRegExpData > regexp_data, DirectHandle< String > subject, int index, int32_t *output, int output_size)
static bool Compile(Isolate *isolate, Zone *zone, RegExpCompileData *input, RegExpFlags flags, DirectHandle< String > pattern, DirectHandle< String > sample_subject, bool is_one_byte, uint32_t &backtrack_limit)
static bool CompileIrregexp(Isolate *isolate, DirectHandle< IrRegExpData > re_data, DirectHandle< String > sample_subject, bool is_one_byte)
static DirectHandle< String > ToString(DirectHandle< Object > value)
@ GLOBAL_NO_ZERO_LENGTH_CHECK
static constexpr int kMaxRegisterCount
static DirectHandle< RegExpMatchInfo > ReserveCaptures(Isolate *isolate, DirectHandle< RegExpMatchInfo > match_info, int capture_count)
static bool VerifyRegExpSyntax(Zone *zone, uintptr_t stack_limit, const CharT *input, int input_length, RegExpFlags flags, RegExpCompileData *result, const DisallowGarbageCollection &no_gc)
static bool ParseRegExpFromHeapString(Isolate *isolate, Zone *zone, DirectHandle< String > input, RegExpFlags flags, RegExpCompileData *result)
int32_t * Initialize(int size)
static bool TryGet(Isolate *isolate, Tagged< String > subject, Tagged< String > pattern, int *number_of_matches_out, int *last_match_index_out)
static constexpr int kNumberOfMatchesIndex
static constexpr int kSubjectIndex
static constexpr int kPatternIndex
static constexpr int kLastMatchIndexIndex
static void TryInsert(Isolate *isolate, Tagged< String > subject, Tagged< String > pattern, int number_of_matches, int last_match_index)
static void Clear(Heap *heap)
static constexpr int kSize
static constexpr int kPatternOffset
@ REGEXP_MULTIPLE_INDICES
@ STRING_SPLIT_SUBSTRINGS
static void Clear(Tagged< FixedArray > cache)
static constexpr int kLastMatchOffset
static void Enter(Isolate *isolate, DirectHandle< String > key_string, DirectHandle< Object > key_pattern, DirectHandle< FixedArray > value_array, DirectHandle< FixedArray > last_match_cache, ResultsCacheType type)
static constexpr int kRegExpResultsCacheSize
static constexpr int kStringOffset
static constexpr int kArrayEntriesPerCacheEntry
static constexpr int kArrayOffset
static Tagged< Object > Lookup(Heap *heap, Tagged< String > key_string, Tagged< Object > key_pattern, Tagged< FixedArray > *last_match_out, ResultsCacheType type)
static bool IsUnmodifiedRegExp(Isolate *isolate, DirectHandle< Object > obj)
static V8_EXPORT_PRIVATE bool CompileForTesting(Isolate *isolate, Zone *zone, RegExpCompileData *input, RegExpFlags flags, DirectHandle< String > pattern, DirectHandle< String > sample_subject, bool is_one_byte)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT std::optional< int > ExperimentalOneshotExec(Isolate *isolate, DirectHandle< JSRegExp > regexp, DirectHandle< String > subject, int index, int32_t *result_offsets_vector, uint32_t result_offsets_vector_length)
static DirectHandle< RegExpMatchInfo > SetLastMatchInfo(Isolate *isolate, DirectHandle< RegExpMatchInfo > last_match_info, DirectHandle< String > subject, int capture_count, int32_t *match)
static V8_EXPORT_PRIVATE intptr_t AtomExecRaw(Isolate *isolate, Address data_address, Address subject_address, int32_t index, int32_t *result_offsets_vector, int32_t result_offsets_vector_length)
static bool VerifySyntax(Zone *zone, uintptr_t stack_limit, const CharT *input, int input_length, RegExpFlags flags, RegExpError *regexp_error_out, const DisallowGarbageCollection &no_gc)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT std::optional< int > Exec(Isolate *isolate, DirectHandle< JSRegExp > regexp, DirectHandle< String > subject, int index, int32_t *result_offsets_vector, uint32_t result_offsets_vector_length)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > Exec_Single(Isolate *isolate, DirectHandle< JSRegExp > regexp, DirectHandle< String > subject, int index, DirectHandle< RegExpMatchInfo > last_match_info)
static V8_EXPORT_PRIVATE void DotPrintForTesting(const char *label, RegExpNode *node)
static bool CanGenerateBytecode()
static DirectHandle< FixedArray > CreateCaptureNameMap(Isolate *isolate, ZoneVector< RegExpCapture * > *named_captures)
static V8_EXPORT_PRIVATE bool VerifyFlags(RegExpFlags flags)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > ThrowRegExpException(Isolate *isolate, RegExpFlags flags, DirectHandle< String > pattern, RegExpError error)
static bool IsUnmodifiedRegExp(Isolate *isolate, DirectHandle< JSRegExp > regexp)
static const int kRegExpTooLargeToOptimize
static V8_WARN_UNUSED_RESULT bool EnsureFullyCompiled(Isolate *isolate, DirectHandle< RegExpData > re_data, DirectHandle< String > subject)
@ RE_FALLBACK_TO_EXPERIMENTAL
static constexpr int kInternalRegExpFallbackToExperimental
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > Compile(Isolate *isolate, DirectHandle< JSRegExp > re, DirectHandle< String > pattern, RegExpFlags flags, uint32_t backtrack_limit)
static constexpr int ToInt(const Tagged< Object > object)
static constexpr Tagged< Smi > FromInt(int value)
static bool constexpr IsValid(T value)
static constexpr Tagged< Smi > zero()
base::Vector< const uint8_t > ToOneByteVector() const
base::Vector< const base::uc16 > ToUC16Vector() const
static V8_INLINE HandleType< String > Flatten(Isolate *isolate, HandleType< T > string, AllocationType allocation=AllocationType::kYoung)
static bool IsOneByteRepresentationUnderneath(Tagged< String > string)
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
#define THROW_NEW_ERROR(isolate, call)
DirectHandle< FixedArray > capture_name_map
ZoneVector< RpoNumber > & result
Vector< const char > CStrVector(const char *data)
constexpr uint32_t kPatternTooShortForBoyerMoore
constexpr uint32_t kMaxLookaheadForBoyerMoore
bool Is(IndirectHandle< U > value)
void PrintF(const char *format,...)
constexpr bool IsEitherUnicode(RegExpFlags f)
constexpr bool ShouldOptionallyStepBackToLeadSurrogate(RegExpFlags f)
void MemsetTagged(Tagged_t *start, Tagged< MaybeObject > value, size_t counter)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
std::ostream & operator<<(std::ostream &os, AtomicMemoryOrder order)
const char * RegExpErrorString(RegExpError error)
V8_EXPORT_PRIVATE FlagValues v8_flags
RegExpError AnalyzeRegExp(Isolate *isolate, bool is_one_byte, RegExpFlags flags, RegExpNode *node)
void RegExpBytecodeDisassemble(const uint8_t *code_base, int length, const char *pattern)
constexpr int kStackSpaceRequiredForCompilation
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage * MB
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
DirectHandle< String > subject_
#define DCHECK_LE(v1, v2)
#define CHECK_LE(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_GE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
ZoneVector< RegExpCapture * > * named_captures
DirectHandle< Object > code
RegExpCompilationTarget compilation_target
DirectHandle< Object > code
#define V8_WARN_UNUSED_RESULT
#define V8_UNLIKELY(condition)