| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 244 |
| 245 static Object* Runtime_RegExpCompile(Arguments args) { | 245 static Object* Runtime_RegExpCompile(Arguments args) { |
| 246 HandleScope scope; // create a new handle scope | 246 HandleScope scope; // create a new handle scope |
| 247 ASSERT(args.length() == 3); | 247 ASSERT(args.length() == 3); |
| 248 CONVERT_CHECKED(JSRegExp, raw_re, args[0]); | 248 CONVERT_CHECKED(JSRegExp, raw_re, args[0]); |
| 249 Handle<JSRegExp> re(raw_re); | 249 Handle<JSRegExp> re(raw_re); |
| 250 CONVERT_CHECKED(String, raw_pattern, args[1]); | 250 CONVERT_CHECKED(String, raw_pattern, args[1]); |
| 251 Handle<String> pattern(raw_pattern); | 251 Handle<String> pattern(raw_pattern); |
| 252 CONVERT_CHECKED(String, raw_flags, args[2]); | 252 CONVERT_CHECKED(String, raw_flags, args[2]); |
| 253 Handle<String> flags(raw_flags); | 253 Handle<String> flags(raw_flags); |
| 254 return *RegExpImpl::JsreCompile(re, pattern, flags); | 254 return *RegExpImpl::Compile(re, pattern, flags); |
| 255 } | 255 } |
| 256 | 256 |
| 257 | 257 |
| 258 static Object* Runtime_CreateApiFunction(Arguments args) { | 258 static Object* Runtime_CreateApiFunction(Arguments args) { |
| 259 HandleScope scope; | 259 HandleScope scope; |
| 260 ASSERT(args.length() == 1); | 260 ASSERT(args.length() == 1); |
| 261 CONVERT_CHECKED(FunctionTemplateInfo, raw_data, args[0]); | 261 CONVERT_CHECKED(FunctionTemplateInfo, raw_data, args[0]); |
| 262 Handle<FunctionTemplateInfo> data(raw_data); | 262 Handle<FunctionTemplateInfo> data(raw_data); |
| 263 return *Factory::CreateApiFunction(data); | 263 return *Factory::CreateApiFunction(data); |
| 264 } | 264 } |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 | 697 |
| 698 static Object* Runtime_RegExpExec(Arguments args) { | 698 static Object* Runtime_RegExpExec(Arguments args) { |
| 699 HandleScope scope; | 699 HandleScope scope; |
| 700 ASSERT(args.length() == 3); | 700 ASSERT(args.length() == 3); |
| 701 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); | 701 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); |
| 702 Handle<JSRegExp> regexp(raw_regexp); | 702 Handle<JSRegExp> regexp(raw_regexp); |
| 703 CONVERT_CHECKED(String, raw_subject, args[1]); | 703 CONVERT_CHECKED(String, raw_subject, args[1]); |
| 704 Handle<String> subject(raw_subject); | 704 Handle<String> subject(raw_subject); |
| 705 Handle<Object> index(args[2]); | 705 Handle<Object> index(args[2]); |
| 706 ASSERT(index->IsNumber()); | 706 ASSERT(index->IsNumber()); |
| 707 return *RegExpImpl::JsreExec(regexp, subject, index); | 707 return *RegExpImpl::Exec(regexp, subject, index); |
| 708 } | 708 } |
| 709 | 709 |
| 710 | 710 |
| 711 static Object* Runtime_RegExpExecGlobal(Arguments args) { | 711 static Object* Runtime_RegExpExecGlobal(Arguments args) { |
| 712 HandleScope scope; | 712 HandleScope scope; |
| 713 ASSERT(args.length() == 2); | 713 ASSERT(args.length() == 2); |
| 714 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); | 714 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); |
| 715 Handle<JSRegExp> regexp(raw_regexp); | 715 Handle<JSRegExp> regexp(raw_regexp); |
| 716 CONVERT_CHECKED(String, raw_subject, args[1]); | 716 CONVERT_CHECKED(String, raw_subject, args[1]); |
| 717 Handle<String> subject(raw_subject); | 717 Handle<String> subject(raw_subject); |
| 718 return *RegExpImpl::JsreExecGlobal(regexp, subject); | 718 return *RegExpImpl::ExecGlobal(regexp, subject); |
| 719 } | 719 } |
| 720 | 720 |
| 721 | 721 |
| 722 static Object* Runtime_MaterializeRegExpLiteral(Arguments args) { | 722 static Object* Runtime_MaterializeRegExpLiteral(Arguments args) { |
| 723 HandleScope scope; | 723 HandleScope scope; |
| 724 ASSERT(args.length() == 4); | 724 ASSERT(args.length() == 4); |
| 725 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 725 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 726 int index = Smi::cast(args[1])->value(); | 726 int index = Smi::cast(args[1])->value(); |
| 727 Handle<String> pattern = args.at<String>(2); | 727 Handle<String> pattern = args.at<String>(2); |
| 728 Handle<String> flags = args.at<String>(3); | 728 Handle<String> flags = args.at<String>(3); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 p = buffer->GetNext(); | 935 p = buffer->GetNext(); |
| 936 if (p == pattern->Get(j)) { | 936 if (p == pattern->Get(j)) { |
| 937 next_table[i] = next_table[j]; | 937 next_table[i] = next_table[j]; |
| 938 } else { | 938 } else { |
| 939 next_table[i] = j; | 939 next_table[i] = j; |
| 940 } | 940 } |
| 941 } | 941 } |
| 942 } | 942 } |
| 943 | 943 |
| 944 | 944 |
| 945 static Object* Runtime_StringIndexOf(Arguments args) { | 945 int Runtime::StringMatchKmp(String* sub, String* pat, int start_index) { |
| 946 NoHandleAllocation ha; | |
| 947 ASSERT(args.length() == 3); | |
| 948 | |
| 949 CONVERT_CHECKED(String, sub, args[0]); | |
| 950 CONVERT_CHECKED(String, pat, args[1]); | |
| 951 Object* index = args[2]; | |
| 952 | |
| 953 sub->TryFlatten(); | 946 sub->TryFlatten(); |
| 954 pat->TryFlatten(); | 947 pat->TryFlatten(); |
| 955 | 948 |
| 956 int subject_length = sub->length(); | 949 int subject_length = sub->length(); |
| 957 int pattern_length = pat->length(); | 950 int pattern_length = pat->length(); |
| 958 | 951 |
| 959 uint32_t start_index; | 952 if (start_index > subject_length) return -1; |
| 960 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); | 953 if (pattern_length == 0) return start_index; |
| 961 if (pattern_length == 0) return Smi::FromInt(start_index); | |
| 962 | 954 |
| 963 // Searching for one specific character is common. For one | 955 // Searching for one specific character is common. For one |
| 964 // character patterns the KMP algorithm is guaranteed to slow down | 956 // character patterns the KMP algorithm is guaranteed to slow down |
| 965 // the search, so we just run through the subject string. | 957 // the search, so we just run through the subject string. |
| 966 if (pattern_length == 1) { | 958 if (pattern_length == 1) { |
| 967 uint16_t pattern_char = pat->Get(0); | 959 uint16_t pattern_char = pat->Get(0); |
| 968 for (int i = start_index; i < subject_length; i++) { | 960 for (int i = start_index; i < subject_length; i++) { |
| 969 if (sub->Get(i) == pattern_char) { | 961 if (sub->Get(i) == pattern_char) { |
| 970 return Smi::FromInt(i); | 962 return i; |
| 971 } | 963 } |
| 972 } | 964 } |
| 973 return Smi::FromInt(-1); | 965 return -1; |
| 974 } | 966 } |
| 975 | 967 |
| 976 // For small searches, KMP is not worth the setup overhead. | 968 // For small searches, KMP is not worth the setup overhead. |
| 977 if (subject_length < 100) { | 969 if (subject_length < 100) { |
| 978 // We know our pattern is at least 2 characters, we cache the first so | 970 // We know our pattern is at least 2 characters, we cache the first so |
| 979 // the common case of the first character not matching is faster. | 971 // the common case of the first character not matching is faster. |
| 980 uint16_t pattern_first_char = pat->Get(0); | 972 uint16_t pattern_first_char = pat->Get(0); |
| 981 for (int i = start_index; i + pattern_length <= subject_length; i++) { | 973 for (int i = start_index; i + pattern_length <= subject_length; i++) { |
| 982 if (sub->Get(i) != pattern_first_char) continue; | 974 if (sub->Get(i) != pattern_first_char) continue; |
| 983 | 975 |
| 984 for (int j = 1; j < pattern_length; j++) { | 976 for (int j = 1; j < pattern_length; j++) { |
| 985 if (pat->Get(j) != sub->Get(j + i)) break; | 977 if (pat->Get(j) != sub->Get(j + i)) break; |
| 986 if (j == pattern_length - 1) return Smi::FromInt(i); | 978 if (j == pattern_length - 1) return i; |
| 987 } | 979 } |
| 988 } | 980 } |
| 989 return Smi::FromInt(-1); | 981 return -1; |
| 990 } | 982 } |
| 991 | 983 |
| 992 // For patterns with a larger length we use the KMP algorithm. | 984 // For patterns with a larger length we use the KMP algorithm. |
| 993 // | 985 // |
| 994 // Compute the 'next' table. | 986 // Compute the 'next' table. |
| 995 int* next_table = NewArray<int>(pattern_length); | 987 int* next_table = NewArray<int>(pattern_length); |
| 996 ComputeKMPNextTable(pat, next_table); | 988 ComputeKMPNextTable(pat, next_table); |
| 997 // Search using the 'next' table. | 989 // Search using the 'next' table. |
| 998 int pattern_index = 0; | 990 int pattern_index = 0; |
| 999 // We would like to use StringInputBuffer here, but it does not have | 991 // We would like to use StringInputBuffer here, but it does not have |
| 1000 // the ability to start anywhere but the first character of a | 992 // the ability to start anywhere but the first character of a |
| 1001 // string. It would be nice to have efficient forward-seeking | 993 // string. It would be nice to have efficient forward-seeking |
| 1002 // support on StringInputBuffers. | 994 // support on StringInputBuffers. |
| 1003 int subject_index = start_index; | 995 int subject_index = start_index; |
| 1004 while (subject_index < subject_length) { | 996 while (subject_index < subject_length) { |
| 1005 uint16_t subject_char = sub->Get(subject_index); | 997 uint16_t subject_char = sub->Get(subject_index); |
| 1006 while (pattern_index > -1 && pat->Get(pattern_index) != subject_char) { | 998 while (pattern_index > -1 && pat->Get(pattern_index) != subject_char) { |
| 1007 pattern_index = next_table[pattern_index]; | 999 pattern_index = next_table[pattern_index]; |
| 1008 } | 1000 } |
| 1009 pattern_index++; | 1001 pattern_index++; |
| 1010 subject_index++; | 1002 subject_index++; |
| 1011 if (pattern_index >= pattern_length) { | 1003 if (pattern_index >= pattern_length) { |
| 1012 DeleteArray(next_table); | 1004 DeleteArray(next_table); |
| 1013 return Smi::FromInt(subject_index - pattern_index); | 1005 return subject_index - pattern_index; |
| 1014 } | 1006 } |
| 1015 } | 1007 } |
| 1016 DeleteArray(next_table); | 1008 DeleteArray(next_table); |
| 1017 return Smi::FromInt(-1); | 1009 return -1; |
| 1018 } | 1010 } |
| 1019 | 1011 |
| 1020 | 1012 |
| 1013 static Object* Runtime_StringIndexOf(Arguments args) { |
| 1014 NoHandleAllocation ha; |
| 1015 ASSERT(args.length() == 3); |
| 1016 |
| 1017 CONVERT_CHECKED(String, sub, args[0]); |
| 1018 CONVERT_CHECKED(String, pat, args[1]); |
| 1019 Object* index = args[2]; |
| 1020 uint32_t start_index; |
| 1021 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); |
| 1022 |
| 1023 return Smi::FromInt(Runtime::StringMatchKmp(sub, pat, start_index)); |
| 1024 } |
| 1025 |
| 1026 |
| 1021 static Object* Runtime_StringLastIndexOf(Arguments args) { | 1027 static Object* Runtime_StringLastIndexOf(Arguments args) { |
| 1022 NoHandleAllocation ha; | 1028 NoHandleAllocation ha; |
| 1023 ASSERT(args.length() == 3); | 1029 ASSERT(args.length() == 3); |
| 1024 | 1030 |
| 1025 CONVERT_CHECKED(String, sub, args[0]); | 1031 CONVERT_CHECKED(String, sub, args[0]); |
| 1026 CONVERT_CHECKED(String, pat, args[1]); | 1032 CONVERT_CHECKED(String, pat, args[1]); |
| 1027 Object* index = args[2]; | 1033 Object* index = args[2]; |
| 1028 | 1034 |
| 1029 sub->TryFlatten(); | 1035 sub->TryFlatten(); |
| 1030 pat->TryFlatten(); | 1036 pat->TryFlatten(); |
| (...skipping 3985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5016 | 5022 |
| 5017 void Runtime::PerformGC(Object* result) { | 5023 void Runtime::PerformGC(Object* result) { |
| 5018 Failure* failure = Failure::cast(result); | 5024 Failure* failure = Failure::cast(result); |
| 5019 // Try to do a garbage collection; ignore it if it fails. The C | 5025 // Try to do a garbage collection; ignore it if it fails. The C |
| 5020 // entry stub will throw an out-of-memory exception in that case. | 5026 // entry stub will throw an out-of-memory exception in that case. |
| 5021 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); | 5027 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); |
| 5022 } | 5028 } |
| 5023 | 5029 |
| 5024 | 5030 |
| 5025 } } // namespace v8::internal | 5031 } } // namespace v8::internal |
| OLD | NEW |