91 template <
typename Char>
95 int length = characters.
length();
97 for (
int i = 0;
i < length;
i++) {
98 Char c = characters[
i];
100 int next_index =
i + 1;
101 if (next_index == length) {
104 Char c2 = characters[next_index];
112 last = next_index + 1;
153 int capture_ref = c2 -
'0';
154 if (capture_ref > capture_count) {
158 int second_digit_index = next_index + 1;
159 if (second_digit_index < length) {
161 Char c3 = characters[second_digit_index];
162 if (
'0' <= c3 && c3 <=
'9') {
163 int double_digit_ref = capture_ref * 10 + c3 -
'0';
164 if (double_digit_ref <= capture_count) {
165 next_index = second_digit_index;
166 capture_ref = double_digit_ref;
170 if (capture_ref > 0) {
175 DCHECK(capture_ref <= capture_count);
177 last = next_index + 1;
206 int subject_length) {
214 capture_count, subject_length,
zone());
218 capture_count, subject_length,
zone());
220 if (simple)
return true;
223 Isolate* isolate = replacement->GetIsolate();
225 int substring_index = 0;
226 for (
int i = 0, n =
parts_.length();
i < n;
i++) {
232 isolate->
factory()->NewSubString(replacement, from,
to),
zone());
234 parts_[
i].data = substring_index;
238 parts_[
i].data = substring_index;
247 int match_from,
int match_to,
int32_t* match) {
249 for (
int i = 0, n =
parts_.length();
i < n;
i++) {
256 int subject_length = part.
data;
257 if (match_to < subject_length) {
263 int capture = part.
data;
264 int from = match[capture * 2];
265 int to = match[capture * 2 + 1];
266 if (from >= 0 &&
to > from) {
288 const uint8_t* subject_start = subject.
start();
289 const uint8_t* subject_end = subject_start + subject.
length();
290 const uint8_t* pos = subject_start;
292 pos =
reinterpret_cast<const uint8_t*
>(
293 memchr(pos, pattern, subject_end - pos));
294 if (pos ==
NULL)
return;
295 indices->
Add(
static_cast<int>(pos - subject_start), zone);
306 const uc16* subject_start = subject.
start();
307 const uc16* subject_end = subject_start + subject.
length();
308 for (
const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
309 if (*pos == pattern) {
310 indices->
Add(
static_cast<int>(pos - subject_start), zone);
317 template <
typename SubjectChar,
typename PatternChar>
324 int pattern_length = pattern.
length();
328 index = search.
Search(subject, index);
329 if (index < 0)
return;
330 indices->
Add(index, zone);
331 index += pattern_length;
339 unsigned int limit,
Zone* zone) {
351 if (pattern_vector.
length() == 1) {
367 if (pattern_vector.
length() == 1) {
376 if (pattern_vector.
length() == 1) {
389 template <
typename ResultSeqString>
393 DCHECK(subject->IsFlat());
394 DCHECK(replacement->IsFlat());
401 int subject_len = subject->length();
402 int pattern_len = pattern->
length();
403 int replacement_len = replacement->length();
408 int matches = indices.length();
409 if (matches == 0)
return *subject;
412 int64_t result_len_64 = (
static_cast<int64_t
>(replacement_len) -
413 static_cast<int64_t
>(pattern_len)) *
414 static_cast<int64_t
>(matches) +
415 static_cast<int64_t
>(subject_len);
421 result_len =
static_cast<int>(result_len_64);
428 if (ResultSeqString::kHasOneByteEncoding) {
429 maybe_res = isolate->
factory()->NewRawOneByteString(result_len);
431 maybe_res = isolate->
factory()->NewRawTwoByteString(result_len);
437 for (
int i = 0;
i < matches;
i++) {
439 if (subject_pos < indices.
at(
i)) {
441 subject_pos, indices.
at(
i));
442 result_pos += indices.
at(
i) - subject_pos;
446 if (replacement_len > 0) {
449 result_pos += replacement_len;
452 subject_pos = indices.
at(
i) + pattern_len;
455 if (subject_pos < subject_len) {
460 int32_t match_indices[] = {indices.
at(matches - 1),
461 indices.
at(matches - 1) + pattern_len};
471 DCHECK(subject->IsFlat());
472 DCHECK(replacement->IsFlat());
474 int capture_count = regexp->CaptureCount();
475 int subject_length = subject->length();
480 bool simple_replace =
481 compiled_replacement.
Compile(replacement, capture_count, subject_length);
485 if (subject->HasOnlyOneByteChars() && replacement->HasOnlyOneByteChars()) {
486 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
487 isolate, subject, regexp, replacement, last_match_info);
489 return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
490 isolate, subject, regexp, replacement, last_match_info);
495 if (global_cache.HasException())
return isolate->
heap()->exception();
497 int32_t* current_match = global_cache.FetchNext();
498 if (current_match ==
NULL) {
499 if (global_cache.HasException())
return isolate->
heap()->exception();
506 int expected_parts = (compiled_replacement.
parts() + 1) * 4 + 1;
512 const int parts_added_per_loop = 2 * (compiled_replacement.
parts() + 2);
519 int start = current_match[0];
520 int end = current_match[1];
526 if (simple_replace) {
529 compiled_replacement.
Apply(&builder, start, end, current_match);
533 current_match = global_cache.FetchNext();
534 }
while (current_match !=
NULL);
536 if (global_cache.HasException())
return isolate->
heap()->exception();
538 if (prev < subject_length) {
544 global_cache.LastSuccessfulMatch());
552 template <
typename ResultSeqString>
556 DCHECK(subject->IsFlat());
561 if (subject->IsOneByteRepresentation()) {
562 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
563 isolate, subject, regexp, empty_string, last_match_info);
565 return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
566 isolate, subject, regexp, empty_string, last_match_info);
571 if (global_cache.HasException())
return isolate->
heap()->exception();
573 int32_t* current_match = global_cache.FetchNext();
574 if (current_match ==
NULL) {
575 if (global_cache.HasException())
return isolate->
heap()->exception();
579 int start = current_match[0];
580 int end = current_match[1];
581 int capture_count = regexp->CaptureCount();
582 int subject_length = subject->length();
584 int new_length = subject_length - (end - start);
585 if (new_length == 0)
return isolate->
heap()->empty_string();
588 if (ResultSeqString::kHasOneByteEncoding) {
590 isolate->
factory()->NewRawOneByteString(new_length).ToHandleChecked());
593 isolate->
factory()->NewRawTwoByteString(new_length).ToHandleChecked());
600 start = current_match[0];
601 end = current_match[1];
605 position += start - prev;
609 current_match = global_cache.FetchNext();
610 }
while (current_match !=
NULL);
612 if (global_cache.HasException())
return isolate->
heap()->exception();
615 global_cache.LastSuccessfulMatch());
617 if (prev < subject_length) {
621 position += subject_length - prev;
624 if (position == 0)
return isolate->
heap()->empty_string();
627 int string_size = ResultSeqString::SizeFor(position);
628 int allocated_string_size = ResultSeqString::SizeFor(new_length);
629 int delta = allocated_string_size - string_size;
631 answer->set_length(position);
632 if (delta == 0)
return *answer;
634 Address end_of_string = answer->address() + string_size;
649 DCHECK(args.length() == 4);
661 if (replacement->length() == 0) {
662 if (subject->HasOnlyOneByteChars()) {
663 return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
664 isolate, subject, regexp, last_match_info);
666 return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
667 isolate, subject, regexp, last_match_info);
674 replacement, last_match_info);
680 DCHECK(args.length() == 3);
686 int subject_length = subject->length();
687 int pattern_length = pattern->length();
690 if (limit == 0xffffffffu) {
710 static const int kMaxInitialListCapacity = 16;
712 ZoneScope zone_scope(isolate->runtime_zone());
715 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
721 if (
static_cast<uint32_t>(indices.length()) < limit) {
722 indices.
Add(subject_length, zone_scope.
zone());
728 int part_count = indices.length();
734 DCHECK(result->HasFastObjectElements());
736 if (part_count == 1 && indices.
at(0) == subject_length) {
737 FixedArray::cast(result->elements())->set(0, *subject);
743 for (
int i = 0;
i < part_count;
i++) {
745 int part_end = indices.
at(
i);
747 isolate->factory()->NewProperSubString(subject, part_start, part_end);
748 elements->set(
i, *substring);
749 part_start = part_end + pattern_length;
752 if (limit == 0xffffffffu) {
753 if (result->HasFastObjectElements()) {
765 DCHECK(args.length() == 3);
778 DCHECK(args.length() == 4);
787 isolate->counters()->regexp_entry_runtime()->Increment();
798 DCHECK(args.length() == 3);
804 Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
806 isolate->factory()->NewJSObjectFromMap(regexp_map,
NOT_TENURED,
false);
808 array->set_elements(*elements);
819 DCHECK(args.length() == 6);
824 if (source->length() == 0) source = isolate->factory()->query_colon_string();
827 if (!global->IsTrue()) global = isolate->factory()->false_value();
830 if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
833 if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
836 if (!sticky->IsTrue()) sticky = isolate->factory()->false_value();
839 Object* constructor =
map->constructor();
840 if (!FLAG_harmony_regexps && constructor->IsJSFunction() &&
841 JSFunction::cast(constructor)->initial_map() ==
map) {
867 Factory* factory = isolate->factory();
869 source,
final).Check();
871 global,
final).Check();
873 regexp, factory->ignore_case_string(), ignoreCase,
final).Check();
875 multiline,
final).Check();
876 if (FLAG_harmony_regexps) {
878 sticky,
final).Check();
881 zero, writable).Check();
888 DCHECK(args.length() == 4);
913 template <
bool has_capture>
918 DCHECK(subject->IsFlat());
919 DCHECK_NE(has_capture, regexp->CaptureCount() == 0);
921 int capture_count = regexp->CaptureCount();
922 int subject_length = subject->length();
924 static const int kMinLengthToCache = 0x1000;
926 if (subject_length > kMinLengthToCache) {
938 Object* cached_fixed_array_last_element =
939 cached_fixed_array->get(cached_fixed_array->length() - 1);
940 Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
941 result_array->set_length(js_array_length);
944 return *result_array;
949 if (global_cache.HasException())
return isolate->
heap()->exception();
952 DCHECK(result_array->HasFastObjectElements());
954 FixedArray::cast(result_array->elements()));
955 if (result_elements->length() < 16) {
956 result_elements = isolate->
factory()->NewFixedArrayWithHoles(16);
962 int match_start = -1;
967 static const int kMaxBuilderEntriesPerRegExpMatch = 5;
970 int32_t* current_match = global_cache.FetchNext();
971 if (current_match ==
NULL)
break;
972 match_start = current_match[0];
974 if (match_end < match_start) {
978 match_end = current_match[1];
984 match = isolate->
factory()->NewProperSubString(subject, match_start,
988 isolate->
factory()->NewSubString(subject, match_start, match_end);
996 isolate->
factory()->NewFixedArray(3 + capture_count);
998 elements->set(0, *match);
999 for (
int i = 1;
i <= capture_count;
i++) {
1000 int start = current_match[
i * 2];
1002 int end = current_match[
i * 2 + 1];
1005 isolate->
factory()->NewSubString(subject, start, end);
1006 elements->set(
i, *substring);
1008 DCHECK(current_match[
i * 2 + 1] < 0);
1009 elements->set(
i, isolate->
heap()->undefined_value());
1012 elements->set(capture_count + 1,
Smi::FromInt(match_start));
1013 elements->set(capture_count + 2, *subject);
1014 builder.
Add(*isolate->
factory()->NewJSArrayWithElements(elements));
1016 builder.
Add(*match);
1021 if (global_cache.HasException())
return isolate->
heap()->exception();
1023 if (match_start >= 0) {
1025 if (match_end < subject_length) {
1033 if (subject_length > kMinLengthToCache) {
1038 fixed_array->set(fixed_array->length() - 1,
1042 handle(regexp->data(), isolate), fixed_array,
1045 return *builder.
ToJSArray(result_array);
1047 return isolate->
heap()->null_value();
1057 DCHECK(args.length() == 4);
1069 if (regexp->CaptureCount() == 0) {
1070 return SearchRegExpMultiple<false>(isolate, subject, regexp,
1071 last_match_info, result_array);
1073 return SearchRegExpMultiple<true>(isolate, subject, regexp, last_match_info,
1080 SealHandleScope shs(isolate);
1081 return __RT_impl_Runtime_RegExpConstructResult(args, isolate);
1086 SealHandleScope shs(isolate);
1087 return __RT_impl_Runtime_RegExpExecRT(args, isolate);
1096 DCHECK(0 <= start_index);
1097 DCHECK(start_index <= sub->length());
1099 int pattern_length = pat->length();
1100 if (pattern_length == 0)
return start_index;
1102 int subject_length = sub->length();
1103 if (start_index + pattern_length > subject_length)
return -1;
A JavaScript value representing a 32-bit unsigned integer.
ZoneList< Handle< String > > replacement_substrings_
bool Compile(Handle< String > replacement, int capture_count, int subject_length)
bool ParseReplacementPattern(ZoneList< ReplacementPart > *parts, Vector< Char > characters, int capture_count, int subject_length, Zone *zone)
ZoneList< ReplacementPart > parts_
void Apply(ReplacementStringBuilder *builder, int match_from, int match_to, int32_t *match)
CompiledReplacement(Zone *zone)
Handle< JSArray > ToJSArray(Handle< JSArray > target_array)
Handle< FixedArray > array()
void EnsureCapacity(int elements)
static const int kMaxLength
static Handle< T > cast(Handle< S > that)
void CreateFillerObjectAt(Address addr, int size)
void AdjustLiveBytes(Address address, int by, InvocationMode mode)
static void SetContent(Handle< JSArray > array, Handle< FixedArrayBase > storage)
static Context * NativeContextFromLiterals(FixedArray *literals)
static void EnsureCanContainHeapObjectElements(Handle< JSObject > obj)
static MUST_USE_RESULT MaybeHandle< Object > SetOwnPropertyIgnoreAttributes(Handle< JSObject > object, Handle< Name > key, Handle< Object > value, PropertyAttributes attributes, ExecutableAccessorInfoHandling handling=DEFAULT_HANDLING)
static const int kIndexIndex
static const int kInputIndex
static const int kSourceFieldIndex
static const int kMultilineFieldIndex
static const int kAtomPatternIndex
static const int kGlobalFieldIndex
static const int kLastIndexFieldIndex
static const int kIgnoreCaseFieldIndex
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
static MUST_USE_RESULT MaybeHandle< Object > Exec(Handle< JSRegExp > regexp, Handle< String > subject, int index, Handle< JSArray > lastMatchInfo)
static Handle< JSArray > SetLastMatchInfo(Handle< JSArray > last_match_info, Handle< String > subject, int capture_count, int32_t *match)
static MUST_USE_RESULT MaybeHandle< Object > CreateRegExpLiteral(Handle< JSFunction > constructor, Handle< String > pattern, Handle< String > flags)
static MUST_USE_RESULT MaybeHandle< Object > Compile(Handle< JSRegExp > re, Handle< String > pattern, Handle< String > flags)
static Object * Lookup(Heap *heap, String *key_string, Object *key_pattern, ResultsCacheType type)
@ REGEXP_MULTIPLE_INDICES
@ STRING_SPLIT_SUBSTRINGS
static void Enter(Isolate *isolate, Handle< String > key_string, Handle< Object > key_pattern, Handle< FixedArray > value_array, ResultsCacheType type)
void AddString(Handle< String > string)
MaybeHandle< String > ToString()
void EnsureCapacity(int elements)
static void AddSubjectSlice(FixedArrayBuilder *builder, int from, int to)
static int StringMatch(Isolate *isolate, Handle< String > sub, Handle< String > pat, int index)
static Smi * FromInt(int value)
int Search(Vector< const SubjectChar > subject, int index)
Vector< const uint8_t > ToOneByteVector()
Vector< const uc16 > ToUC16Vector()
static void WriteToFlat(String *source, sinkchar *sink, int from, int to)
FlatContent GetFlatContent()
static const int kMaxLength
static Handle< String > Flatten(Handle< String > string, PretenureFlag pretenure=NOT_TENURED)
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes to(mksnapshot only)") DEFINE_STRING(raw_context_file
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric literals(0o77, 0b11)") DEFINE_BOOL(harmony_object_literals
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
int SearchString(Isolate *isolate, Vector< const SubjectChar > subject, Vector< const PatternChar > pattern, int start_index)
static Object * SearchRegExpMultiple(Isolate *isolate, Handle< String > subject, Handle< JSRegExp > regexp, Handle< JSArray > last_match_array, Handle< JSArray > result_array)
void FindTwoByteStringIndices(const Vector< const uc16 > subject, uc16 pattern, ZoneList< int > *indices, unsigned int limit, Zone *zone)
static MUST_USE_RESULT Object * StringReplaceGlobalRegExpWithString(Isolate *isolate, Handle< String > subject, Handle< JSRegExp > regexp, Handle< String > replacement, Handle< JSArray > last_match_info)
void FindOneByteStringIndices(Vector< const uint8_t > subject, char pattern, ZoneList< int > *indices, unsigned int limit, Zone *zone)
Handle< T > handle(T *t, Isolate *isolate)
void FindStringIndices(Isolate *isolate, Vector< const SubjectChar > subject, Vector< const PatternChar > pattern, ZoneList< int > *indices, unsigned int limit, Zone *zone)
static MUST_USE_RESULT Object * StringReplaceGlobalRegExpWithEmptyString(Isolate *isolate, Handle< String > subject, Handle< JSRegExp > regexp, Handle< JSArray > last_match_info)
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
static MUST_USE_RESULT Object * StringReplaceGlobalAtomRegExpWithString(Isolate *isolate, Handle< String > subject, Handle< JSRegExp > pattern_regexp, Handle< String > replacement, Handle< JSArray > last_match_info)
void FindStringIndicesDispatch(Isolate *isolate, String *subject, String *pattern, ZoneList< int > *indices, unsigned int limit, Zone *zone)
Debugger support for the V8 JavaScript engine.
#define RUNTIME_ASSERT(value)
#define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)
#define CONVERT_NUMBER_CHECKED(type, name, Type, obj)
#define CONVERT_INT32_ARG_CHECKED(name, index)
#define CONVERT_SMI_ARG_CHECKED(name, index)
static ReplacementPart ReplacementString()
ReplacementPart(int tag, int data)
static ReplacementPart ReplacementSubString(int from, int to)
static ReplacementPart SubjectSuffix(int subject_length)
static ReplacementPart SubjectMatch()
static ReplacementPart SubjectPrefix()
static ReplacementPart SubjectCapture(int capture_index)