23 v8_flags.enable_experimental_regexp_engine_on_excessive_backtracks);
26 if (!can_be_handled &&
v8_flags.trace_experimental_regexp_engine) {
27 StdoutStream{} <<
"Pattern not supported by experimental engine: "
30 return can_be_handled;
37 if (
v8_flags.trace_experimental_regexp_engine) {
38 StdoutStream{} <<
"Initializing experimental regexp " << *source
42 isolate->factory()->SetRegExpExperimentalData(
51 if (
v8_flags.verify_heap) re_data->IrRegExpDataVerify(isolate);
54 static constexpr bool kIsLatin1 =
true;
55 return re_data->has_bytecode(kIsLatin1);
61 static_assert(std::is_trivial_v<T>);
63 int byte_length =
sizeof(
T) * data.length();
65 isolate->factory()->NewTrustedByteArray(byte_length);
67 MemCopy(byte_array->begin(), data.begin(), byte_length);
73struct CompilationResult {
74 DirectHandle<TrustedByteArray> bytecode;
79std::optional<CompilationResult> CompileImpl(
80 Isolate* isolate, DirectHandle<IrRegExpData> re_data) {
83 DirectHandle<String>
source(re_data->source(), isolate);
86 RegExpCompileData parse_result;
87 DCHECK(!isolate->has_exception());
91 isolate, &zone, source, flags, &parse_result);
95 DCHECK_EQ(parse_result.error, RegExpError::kStackOverflow);
118 if (
v8_flags.verify_heap) re_data->IrRegExpDataVerify(isolate);
122 if (
v8_flags.trace_experimental_regexp_engine) {
123 StdoutStream{} <<
"Compiling experimental regexp " << *source << std::endl;
126 std::optional<CompilationResult> compilation_result =
127 CompileImpl(isolate, re_data);
128 if (!compilation_result.has_value()) {
129 DCHECK(isolate->has_exception());
133 re_data->SetBytecodeForExperimental(isolate, *compilation_result->bytecode);
134 re_data->set_capture_name_map(compilation_result->capture_name_map);
152 int capture_count, int32_t* output_registers,
153 int32_t output_register_count, int32_t subject_index) {
158 int register_count_per_match =
162 DCHECK(subject->IsFlat());
165 isolate,
call_origin, bytecode, register_count_per_match, subject,
166 subject_index, output_registers, output_register_count, &zone);
177 int32_t* output_registers,
178 int32_t output_register_count,
179 int32_t subject_index) {
183 if (
v8_flags.trace_experimental_regexp_engine) {
184 StdoutStream{} <<
"Executing experimental regexp " << regexp_data->source()
188 static constexpr bool kIsLatin1 =
true;
191 return ExecRawImpl(isolate,
call_origin, bytecode, subject,
192 regexp_data->capture_count(), output_registers,
193 output_register_count, subject_index);
198 Address input_end,
int* output_registers, int32_t output_register_count,
206 DisallowJavascriptExecution no_js(isolate);
216 output_registers, output_register_count, start_position);
223 uint32_t result_offsets_vector_length) {
227 if (
v8_flags.verify_heap) regexp_data->IrRegExpDataVerify(isolate);
231 DCHECK(isolate->has_exception());
245 result_offsets_vector, result_offsets_vector_length, index);
247 if (num_matches > 0) {
249 regexp_data->capture_count()),
250 result_offsets_vector_length);
252 }
else if (num_matches == 0) {
260 DCHECK(isolate->has_exception());
270 int32_t output_register_count, int32_t subject_index) {
271 CHECK(
v8_flags.enable_experimental_regexp_engine_on_excessive_backtracks);
273 if (
v8_flags.trace_experimental_regexp_engine) {
274 StdoutStream{} <<
"Experimental execution (oneshot) of regexp "
275 << regexp_data->source() << std::endl;
278 std::optional<CompilationResult> compilation_result =
279 CompileImpl(isolate, regexp_data);
284 *compilation_result->bytecode, *subject,
285 regexp_data->capture_count(), output_registers,
286 output_register_count, subject_index);
292 int32_t* result_offsets_vector, uint32_t result_offsets_vector_length) {
293 DCHECK(
v8_flags.enable_experimental_regexp_engine_on_excessive_backtracks);
297 OneshotExecRaw(isolate, regexp_data, subject, result_offsets_vector,
298 result_offsets_vector_length, subject_index);
300 if (num_matches > 0) {
302 regexp_data->capture_count()),
303 result_offsets_vector_length);
305 }
else if (num_matches == 0) {
313 DCHECK(isolate->has_exception());
static ZoneList< RegExpInstruction > Compile(RegExpTree *tree, RegExpFlags flags, Zone *zone)
static bool CanBeHandled(RegExpTree *tree, RegExpFlags flags, int capture_count)
static int FindMatches(Isolate *isolate, RegExp::CallOrigin call_origin, Tagged< TrustedByteArray > bytecode, int capture_count, Tagged< String > input, int start_index, int32_t *output_registers, int output_register_count, Zone *zone)
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 int32_t MatchForCallFromJs(Address subject, int32_t start_position, Address input_start, Address input_end, int *output_registers, int32_t output_register_count, RegExp::CallOrigin call_origin, Isolate *isolate, Address regexp_data)
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)
static constexpr RegExpFlags AsRegExpFlags(Flags f)
static constexpr Flags AsJSRegExpFlags(RegExpFlags f)
static constexpr int RegistersForCaptureCount(int count)
static bool ParseRegExpFromHeapString(Isolate *isolate, Zone *zone, DirectHandle< String > input, RegExpFlags flags, RegExpCompileData *result)
static constexpr int kInternalRegExpException
static DirectHandle< FixedArray > CreateCaptureNameMap(Isolate *isolate, ZoneVector< RegExpCapture * > *named_captures)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > ThrowRegExpException(Isolate *isolate, RegExpFlags flags, DirectHandle< String > pattern, RegExpError error)
static constexpr int kInternalRegExpRetry
static V8_INLINE HandleType< String > Flatten(Isolate *isolate, HandleType< T > string, AllocationType allocation=AllocationType::kYoung)
DirectHandle< FixedArray > capture_name_map
ZoneVector< RpoNumber > & result
InstructionOperand source
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
Tagged(T object) -> Tagged< T >
PerThreadAssertScopeDebugOnly< false, GC_MOLE > DisableGCMole
base::Flags< RegExpFlag > RegExpFlags
DirectHandle< TrustedByteArray > VectorToByteArray(Isolate *isolate, base::Vector< T > data)
V8_EXPORT_PRIVATE FlagValues v8_flags
base::Vector< RegExpInstruction > AsInstructionSequence(Tagged< TrustedByteArray > raw_bytes)
void MemCopy(void *dest, const void *src, size_t size)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
#define DCHECK_LE(v1, v2)
#define DCHECK_NOT_NULL(val)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)