OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/regexp/regexp-utils.h" | 5 #include "src/regexp/regexp-utils.h" |
6 | 6 |
7 #include "src/factory.h" | 7 #include "src/factory.h" |
8 #include "src/isolate.h" | 8 #include "src/isolate.h" |
9 #include "src/objects-inl.h" | 9 #include "src/objects-inl.h" |
10 #include "src/regexp/jsregexp.h" | 10 #include "src/regexp/jsregexp.h" |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 | 138 |
139 // Check the receiver's map. | 139 // Check the receiver's map. |
140 Handle<JSFunction> regexp_function = isolate->regexp_function(); | 140 Handle<JSFunction> regexp_function = isolate->regexp_function(); |
141 if (recv->map() != regexp_function->initial_map()) return false; | 141 if (recv->map() != regexp_function->initial_map()) return false; |
142 | 142 |
143 // Check the receiver's prototype's map. | 143 // Check the receiver's prototype's map. |
144 Object* proto = recv->map()->prototype(); | 144 Object* proto = recv->map()->prototype(); |
145 if (!proto->IsJSReceiver()) return false; | 145 if (!proto->IsJSReceiver()) return false; |
146 | 146 |
147 Handle<Map> initial_proto_initial_map = isolate->regexp_prototype_map(); | 147 Handle<Map> initial_proto_initial_map = isolate->regexp_prototype_map(); |
148 return (JSReceiver::cast(proto)->map() == *initial_proto_initial_map); | 148 if (JSReceiver::cast(proto)->map() != *initial_proto_initial_map) { |
| 149 return false; |
| 150 } |
| 151 |
| 152 // The smi check is required to omit ToLength(lastIndex) calls with possible |
| 153 // user-code execution on the fast path. |
| 154 Object* last_index = JSRegExp::cast(recv)->LastIndex(); |
| 155 return last_index->IsSmi() && Smi::cast(last_index)->value() >= 0; |
149 } | 156 } |
150 | 157 |
151 int RegExpUtils::AdvanceStringIndex(Isolate* isolate, Handle<String> string, | 158 int RegExpUtils::AdvanceStringIndex(Isolate* isolate, Handle<String> string, |
152 int index, bool unicode) { | 159 int index, bool unicode) { |
153 if (unicode && index < string->length()) { | 160 if (unicode && index < string->length()) { |
154 const uint16_t first = string->Get(index); | 161 const uint16_t first = string->Get(index); |
155 if (first >= 0xD800 && first <= 0xDBFF && string->length() > index + 1) { | 162 if (first >= 0xD800 && first <= 0xDBFF && string->length() > index + 1) { |
156 const uint16_t second = string->Get(index + 1); | 163 const uint16_t second = string->Get(index + 1); |
157 if (second >= 0xDC00 && second <= 0xDFFF) { | 164 if (second >= 0xDC00 && second <= 0xDFFF) { |
158 return index + 2; | 165 return index + 2; |
(...skipping 17 matching lines...) Expand all Loading... |
176 Object::ToLength(isolate, last_index_obj), Object); | 183 Object::ToLength(isolate, last_index_obj), Object); |
177 const int last_index = PositiveNumberToUint32(*last_index_obj); | 184 const int last_index = PositiveNumberToUint32(*last_index_obj); |
178 const int new_last_index = | 185 const int new_last_index = |
179 AdvanceStringIndex(isolate, string, last_index, unicode); | 186 AdvanceStringIndex(isolate, string, last_index, unicode); |
180 | 187 |
181 return SetLastIndex(isolate, regexp, new_last_index); | 188 return SetLastIndex(isolate, regexp, new_last_index); |
182 } | 189 } |
183 | 190 |
184 } // namespace internal | 191 } // namespace internal |
185 } // namespace v8 | 192 } // namespace v8 |
OLD | NEW |