| OLD | NEW |
| 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/regexp/jsregexp-inl.h" | 8 #include "src/regexp/jsregexp-inl.h" |
| 9 #include "src/string-builder.h" | 9 #include "src/string-builder.h" |
| 10 #include "src/string-search.h" | 10 #include "src/string-search.h" |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 CONVERT_ARG_HANDLE_CHECKED(Object, index, 2); | 96 CONVERT_ARG_HANDLE_CHECKED(Object, index, 2); |
| 97 | 97 |
| 98 uint32_t start_index = 0; | 98 uint32_t start_index = 0; |
| 99 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); | 99 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); |
| 100 | 100 |
| 101 CHECK(start_index <= static_cast<uint32_t>(sub->length())); | 101 CHECK(start_index <= static_cast<uint32_t>(sub->length())); |
| 102 int position = String::IndexOf(isolate, sub, pat, start_index); | 102 int position = String::IndexOf(isolate, sub, pat, start_index); |
| 103 return Smi::FromInt(position); | 103 return Smi::FromInt(position); |
| 104 } | 104 } |
| 105 | 105 |
| 106 | 106 RUNTIME_FUNCTION(Runtime_StringLastIndexOf) { |
| 107 template <typename schar, typename pchar> | 107 HandleScope handle_scope(isolate); |
| 108 static int StringMatchBackwards(Vector<const schar> subject, | 108 return String::LastIndexOf(isolate, args.at<Object>(0), args.at<Object>(1), |
| 109 Vector<const pchar> pattern, int idx) { | 109 isolate->factory()->undefined_value()); |
| 110 int pattern_length = pattern.length(); | |
| 111 DCHECK(pattern_length >= 1); | |
| 112 DCHECK(idx + pattern_length <= subject.length()); | |
| 113 | |
| 114 if (sizeof(schar) == 1 && sizeof(pchar) > 1) { | |
| 115 for (int i = 0; i < pattern_length; i++) { | |
| 116 uc16 c = pattern[i]; | |
| 117 if (c > String::kMaxOneByteCharCode) { | |
| 118 return -1; | |
| 119 } | |
| 120 } | |
| 121 } | |
| 122 | |
| 123 pchar pattern_first_char = pattern[0]; | |
| 124 for (int i = idx; i >= 0; i--) { | |
| 125 if (subject[i] != pattern_first_char) continue; | |
| 126 int j = 1; | |
| 127 while (j < pattern_length) { | |
| 128 if (pattern[j] != subject[i + j]) { | |
| 129 break; | |
| 130 } | |
| 131 j++; | |
| 132 } | |
| 133 if (j == pattern_length) { | |
| 134 return i; | |
| 135 } | |
| 136 } | |
| 137 return -1; | |
| 138 } | 110 } |
| 139 | 111 |
| 140 | |
| 141 RUNTIME_FUNCTION(Runtime_StringLastIndexOf) { | |
| 142 HandleScope scope(isolate); | |
| 143 DCHECK(args.length() == 3); | |
| 144 | |
| 145 CONVERT_ARG_HANDLE_CHECKED(String, sub, 0); | |
| 146 CONVERT_ARG_HANDLE_CHECKED(String, pat, 1); | |
| 147 CONVERT_ARG_HANDLE_CHECKED(Object, index, 2); | |
| 148 | |
| 149 uint32_t start_index = 0; | |
| 150 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); | |
| 151 | |
| 152 uint32_t pat_length = pat->length(); | |
| 153 uint32_t sub_length = sub->length(); | |
| 154 | |
| 155 if (start_index + pat_length > sub_length) { | |
| 156 start_index = sub_length - pat_length; | |
| 157 } | |
| 158 | |
| 159 if (pat_length == 0) { | |
| 160 return Smi::FromInt(start_index); | |
| 161 } | |
| 162 | |
| 163 sub = String::Flatten(sub); | |
| 164 pat = String::Flatten(pat); | |
| 165 | |
| 166 int position = -1; | |
| 167 DisallowHeapAllocation no_gc; // ensure vectors stay valid | |
| 168 | |
| 169 String::FlatContent sub_content = sub->GetFlatContent(); | |
| 170 String::FlatContent pat_content = pat->GetFlatContent(); | |
| 171 | |
| 172 if (pat_content.IsOneByte()) { | |
| 173 Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector(); | |
| 174 if (sub_content.IsOneByte()) { | |
| 175 position = StringMatchBackwards(sub_content.ToOneByteVector(), pat_vector, | |
| 176 start_index); | |
| 177 } else { | |
| 178 position = StringMatchBackwards(sub_content.ToUC16Vector(), pat_vector, | |
| 179 start_index); | |
| 180 } | |
| 181 } else { | |
| 182 Vector<const uc16> pat_vector = pat_content.ToUC16Vector(); | |
| 183 if (sub_content.IsOneByte()) { | |
| 184 position = StringMatchBackwards(sub_content.ToOneByteVector(), pat_vector, | |
| 185 start_index); | |
| 186 } else { | |
| 187 position = StringMatchBackwards(sub_content.ToUC16Vector(), pat_vector, | |
| 188 start_index); | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 return Smi::FromInt(position); | |
| 193 } | |
| 194 | |
| 195 | |
| 196 RUNTIME_FUNCTION(Runtime_SubString) { | 112 RUNTIME_FUNCTION(Runtime_SubString) { |
| 197 HandleScope scope(isolate); | 113 HandleScope scope(isolate); |
| 198 DCHECK(args.length() == 3); | 114 DCHECK(args.length() == 3); |
| 199 | 115 |
| 200 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); | 116 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); |
| 201 int start, end; | 117 int start, end; |
| 202 // We have a fast integer-only case here to avoid a conversion to double in | 118 // We have a fast integer-only case here to avoid a conversion to double in |
| 203 // the common case where from and to are Smis. | 119 // the common case where from and to are Smis. |
| 204 if (args[1]->IsSmi() && args[2]->IsSmi()) { | 120 if (args[1]->IsSmi() && args[2]->IsSmi()) { |
| 205 CONVERT_SMI_ARG_CHECKED(from_number, 1); | 121 CONVERT_SMI_ARG_CHECKED(from_number, 1); |
| (...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 SealHandleScope shs(isolate); | 1046 SealHandleScope shs(isolate); |
| 1131 DCHECK(args.length() == 2); | 1047 DCHECK(args.length() == 2); |
| 1132 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); | 1048 if (!args[0]->IsString()) return isolate->heap()->undefined_value(); |
| 1133 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); | 1049 if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); |
| 1134 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); | 1050 if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); |
| 1135 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); | 1051 return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); |
| 1136 } | 1052 } |
| 1137 | 1053 |
| 1138 } // namespace internal | 1054 } // namespace internal |
| 1139 } // namespace v8 | 1055 } // namespace v8 |
| OLD | NEW |