Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(762)

Side by Side Diff: src/runtime/runtime-regexp.cc

Issue 1448933002: Introduce a BuiltinsConstructStub that sets up new.target and does a [[call]] per ES6 9.3.2 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/runtime/runtime-proxy.cc ('k') | src/types.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/runtime/runtime-utils.h" 5 #include "src/runtime/runtime-utils.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/conversions-inl.h" 8 #include "src/conversions-inl.h"
9 #include "src/isolate-inl.h" 9 #include "src/isolate-inl.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 Handle<JSArray> array = Handle<JSArray>::cast(object); 818 Handle<JSArray> array = Handle<JSArray>::cast(object);
819 array->set_elements(*elements); 819 array->set_elements(*elements);
820 array->set_length(Smi::FromInt(size)); 820 array->set_length(Smi::FromInt(size));
821 // Write in-object properties after the length of the array. 821 // Write in-object properties after the length of the array.
822 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index); 822 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
823 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input); 823 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
824 return *array; 824 return *array;
825 } 825 }
826 826
827 827
828 static JSRegExp::Flags RegExpFlagsFromString(Handle<String> flags,
829 bool* success) {
830 uint32_t value = JSRegExp::NONE;
831 int length = flags->length();
832 // A longer flags string cannot be valid.
833 if (length > 5) return JSRegExp::Flags(0);
834 for (int i = 0; i < length; i++) {
835 uint32_t flag = JSRegExp::NONE;
836 switch (flags->Get(i)) {
837 case 'g':
838 flag = JSRegExp::GLOBAL;
839 break;
840 case 'i':
841 flag = JSRegExp::IGNORE_CASE;
842 break;
843 case 'm':
844 flag = JSRegExp::MULTILINE;
845 break;
846 case 'u':
847 if (!FLAG_harmony_unicode_regexps) return JSRegExp::Flags(0);
848 flag = JSRegExp::UNICODE_ESCAPES;
849 break;
850 case 'y':
851 if (!FLAG_harmony_regexps) return JSRegExp::Flags(0);
852 flag = JSRegExp::STICKY;
853 break;
854 default:
855 return JSRegExp::Flags(0);
856 }
857 // Duplicate flag.
858 if (value & flag) return JSRegExp::Flags(0);
859 value |= flag;
860 }
861 *success = true;
862 return JSRegExp::Flags(value);
863 }
864
865
866 template <typename Char>
867 inline int CountRequiredEscapes(Handle<String> source) {
868 DisallowHeapAllocation no_gc;
869 int escapes = 0;
870 Vector<const Char> src = source->GetCharVector<Char>();
871 for (int i = 0; i < src.length(); i++) {
872 if (src[i] == '/' && (i == 0 || src[i - 1] != '\\')) escapes++;
873 }
874 return escapes;
875 }
876
877
878 template <typename Char, typename StringType>
879 inline Handle<StringType> WriteEscapedRegExpSource(Handle<String> source,
880 Handle<StringType> result) {
881 DisallowHeapAllocation no_gc;
882 Vector<const Char> src = source->GetCharVector<Char>();
883 Vector<Char> dst(result->GetChars(), result->length());
884 int s = 0;
885 int d = 0;
886 while (s < src.length()) {
887 if (src[s] == '/' && (s == 0 || src[s - 1] != '\\')) dst[d++] = '\\';
888 dst[d++] = src[s++];
889 }
890 DCHECK_EQ(result->length(), d);
891 return result;
892 }
893
894
895 MaybeHandle<String> EscapeRegExpSource(Isolate* isolate,
896 Handle<String> source) {
897 String::Flatten(source);
898 if (source->length() == 0) return isolate->factory()->query_colon_string();
899 bool one_byte = source->IsOneByteRepresentationUnderneath();
900 int escapes = one_byte ? CountRequiredEscapes<uint8_t>(source)
901 : CountRequiredEscapes<uc16>(source);
902 if (escapes == 0) return source;
903 int length = source->length() + escapes;
904 if (one_byte) {
905 Handle<SeqOneByteString> result;
906 ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
907 isolate->factory()->NewRawOneByteString(length),
908 String);
909 return WriteEscapedRegExpSource<uint8_t>(source, result);
910 } else {
911 Handle<SeqTwoByteString> result;
912 ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
913 isolate->factory()->NewRawTwoByteString(length),
914 String);
915 return WriteEscapedRegExpSource<uc16>(source, result);
916 }
917 }
918
919
920 RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) { 828 RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) {
921 HandleScope scope(isolate); 829 HandleScope scope(isolate);
922 DCHECK(args.length() == 3); 830 DCHECK(args.length() == 3);
923 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); 831 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
924 CONVERT_ARG_HANDLE_CHECKED(String, source, 1); 832 CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
925 CONVERT_ARG_HANDLE_CHECKED(String, flags_string, 2); 833 CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
926 Factory* factory = isolate->factory();
927 // If source is the empty string we set it to "(?:)" instead as
928 // suggested by ECMA-262, 5th, section 15.10.4.1.
929 if (source->length() == 0) source = factory->query_colon_string();
930 834
931 bool success = false; 835 RETURN_FAILURE_ON_EXCEPTION(isolate,
932 JSRegExp::Flags flags = RegExpFlagsFromString(flags_string, &success); 836 JSRegExp::Initialize(regexp, source, flags));
933 if (!success) {
934 THROW_NEW_ERROR_RETURN_FAILURE(
935 isolate,
936 NewSyntaxError(MessageTemplate::kInvalidRegExpFlags, flags_string));
937 }
938 837
939 Handle<String> escaped_source; 838 return *regexp;
940 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, escaped_source,
941 EscapeRegExpSource(isolate, source));
942
943 regexp->set_source(*escaped_source);
944 regexp->set_flags(Smi::FromInt(flags.value()));
945
946 Map* map = regexp->map();
947 Object* constructor = map->GetConstructor();
948 if (constructor->IsJSFunction() &&
949 JSFunction::cast(constructor)->initial_map() == map) {
950 // If we still have the original map, set in-object properties directly.
951 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
952 Smi::FromInt(0), SKIP_WRITE_BARRIER);
953 } else {
954 // Map has changed, so use generic, but slower, method.
955 PropertyAttributes writable =
956 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
957 JSObject::SetOwnPropertyIgnoreAttributes(
958 regexp, factory->last_index_string(),
959 Handle<Smi>(Smi::FromInt(0), isolate), writable)
960 .Check();
961 }
962
963 Handle<Object> result;
964 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
965 isolate, result, RegExpImpl::Compile(regexp, source, flags));
966 return *result;
967 } 839 }
968 840
969 841
970 RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) { 842 RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) {
971 HandleScope scope(isolate); 843 HandleScope scope(isolate);
972 DCHECK(args.length() == 4); 844 DCHECK(args.length() == 4);
973 CONVERT_ARG_HANDLE_CHECKED(LiteralsArray, literals, 0); 845 CONVERT_ARG_HANDLE_CHECKED(LiteralsArray, literals, 0);
974 CONVERT_SMI_ARG_CHECKED(index, 1); 846 CONVERT_SMI_ARG_CHECKED(index, 1);
975 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); 847 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
976 CONVERT_ARG_HANDLE_CHECKED(String, flags, 3); 848 CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
977 849
978 Handle<JSFunction> constructor = isolate->regexp_function(); 850 Handle<JSRegExp> regexp;
979 // Compute the regular expression literal. 851 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, regexp,
980 Handle<Object> regexp; 852 JSRegExp::New(pattern, flags));
981 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
982 isolate, regexp,
983 RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
984 literals->set_literal(index, *regexp); 853 literals->set_literal(index, *regexp);
985 return *regexp; 854 return *regexp;
986 } 855 }
987 856
988 857
989 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain 858 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
990 // separate last match info. See comment on that function. 859 // separate last match info. See comment on that function.
991 template <bool has_capture> 860 template <bool has_capture>
992 static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject, 861 static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject,
993 Handle<JSRegExp> regexp, 862 Handle<JSRegExp> regexp,
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 1038
1170 1039
1171 RUNTIME_FUNCTION(Runtime_IsRegExp) { 1040 RUNTIME_FUNCTION(Runtime_IsRegExp) {
1172 SealHandleScope shs(isolate); 1041 SealHandleScope shs(isolate);
1173 DCHECK(args.length() == 1); 1042 DCHECK(args.length() == 1);
1174 CONVERT_ARG_CHECKED(Object, obj, 0); 1043 CONVERT_ARG_CHECKED(Object, obj, 0);
1175 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); 1044 return isolate->heap()->ToBoolean(obj->IsJSRegExp());
1176 } 1045 }
1177 } // namespace internal 1046 } // namespace internal
1178 } // namespace v8 1047 } // namespace v8
OLDNEW
« no previous file with comments | « src/runtime/runtime-proxy.cc ('k') | src/types.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698