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 <functional> | 7 #include <functional> |
8 | 8 |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/conversions-inl.h" | 10 #include "src/conversions-inl.h" |
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 | 1109 |
1110 bool has_named_captures_; | 1110 bool has_named_captures_; |
1111 Handle<JSReceiver> groups_obj_; | 1111 Handle<JSReceiver> groups_obj_; |
1112 }; | 1112 }; |
1113 | 1113 |
1114 // Create the groups object (see also the RegExp result creation in | 1114 // Create the groups object (see also the RegExp result creation in |
1115 // RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo). | 1115 // RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo). |
1116 Handle<JSObject> ConstructNamedCaptureGroupsObject( | 1116 Handle<JSObject> ConstructNamedCaptureGroupsObject( |
1117 Isolate* isolate, Handle<FixedArray> capture_map, | 1117 Isolate* isolate, Handle<FixedArray> capture_map, |
1118 std::function<Object*(int)> f_get_capture) { | 1118 std::function<Object*(int)> f_get_capture) { |
| 1119 DCHECK(FLAG_harmony_regexp_named_captures); |
1119 Handle<JSObject> groups = isolate->factory()->NewJSObjectWithNullProto(); | 1120 Handle<JSObject> groups = isolate->factory()->NewJSObjectWithNullProto(); |
1120 | 1121 |
1121 const int capture_count = capture_map->length() >> 1; | 1122 const int capture_count = capture_map->length() >> 1; |
1122 for (int i = 0; i < capture_count; i++) { | 1123 for (int i = 0; i < capture_count; i++) { |
1123 const int name_ix = i * 2; | 1124 const int name_ix = i * 2; |
1124 const int index_ix = i * 2 + 1; | 1125 const int index_ix = i * 2 + 1; |
1125 | 1126 |
1126 Handle<String> capture_name(String::cast(capture_map->get(name_ix))); | 1127 Handle<String> capture_name(String::cast(capture_map->get(name_ix))); |
1127 const int capture_ix = Smi::cast(capture_map->get(index_ix))->value(); | 1128 const int capture_ix = Smi::cast(capture_map->get(index_ix))->value(); |
1128 DCHECK(1 <= capture_ix && capture_ix <= capture_count); | 1129 DCHECK(1 <= capture_ix && capture_ix <= capture_count); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1221 first = false; | 1222 first = false; |
1222 } | 1223 } |
1223 | 1224 |
1224 if (has_capture) { | 1225 if (has_capture) { |
1225 // Arguments array to replace function is match, captures, index and | 1226 // Arguments array to replace function is match, captures, index and |
1226 // subject, i.e., 3 + capture count in total. If the RegExp contains | 1227 // subject, i.e., 3 + capture count in total. If the RegExp contains |
1227 // named captures, they are also passed as the last argument. | 1228 // named captures, they are also passed as the last argument. |
1228 | 1229 |
1229 Handle<Object> maybe_capture_map(regexp->CaptureNameMap(), isolate); | 1230 Handle<Object> maybe_capture_map(regexp->CaptureNameMap(), isolate); |
1230 const bool has_named_captures = maybe_capture_map->IsFixedArray(); | 1231 const bool has_named_captures = maybe_capture_map->IsFixedArray(); |
| 1232 DCHECK_IMPLIES(has_named_captures, FLAG_harmony_regexp_named_captures); |
1231 | 1233 |
1232 const int argc = | 1234 const int argc = |
1233 has_named_captures ? 4 + capture_count : 3 + capture_count; | 1235 has_named_captures ? 4 + capture_count : 3 + capture_count; |
1234 | 1236 |
1235 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(argc); | 1237 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(argc); |
1236 int cursor = 0; | 1238 int cursor = 0; |
1237 | 1239 |
1238 elements->set(cursor++, *match); | 1240 elements->set(cursor++, *match); |
1239 for (int i = 1; i <= capture_count; i++) { | 1241 for (int i = 1; i <= capture_count; i++) { |
1240 int start = current_match[i * 2]; | 1242 int start = current_match[i * 2]; |
1241 if (start >= 0) { | 1243 if (start >= 0) { |
1242 int end = current_match[i * 2 + 1]; | 1244 int end = current_match[i * 2 + 1]; |
1243 DCHECK(start <= end); | 1245 DCHECK(start <= end); |
1244 Handle<String> substring = | 1246 Handle<String> substring = |
1245 isolate->factory()->NewSubString(subject, start, end); | 1247 isolate->factory()->NewSubString(subject, start, end); |
1246 elements->set(cursor++, *substring); | 1248 elements->set(cursor++, *substring); |
1247 } else { | 1249 } else { |
1248 DCHECK(current_match[i * 2 + 1] < 0); | 1250 DCHECK(current_match[i * 2 + 1] < 0); |
1249 elements->set(cursor++, isolate->heap()->undefined_value()); | 1251 elements->set(cursor++, isolate->heap()->undefined_value()); |
1250 } | 1252 } |
1251 } | 1253 } |
1252 | 1254 |
1253 elements->set(cursor++, Smi::FromInt(match_start)); | 1255 elements->set(cursor++, Smi::FromInt(match_start)); |
1254 elements->set(cursor++, *subject); | 1256 elements->set(cursor++, *subject); |
1255 | 1257 |
1256 if (has_named_captures) { | 1258 if (has_named_captures) { |
1257 DCHECK(FLAG_harmony_regexp_named_captures); | |
1258 Handle<FixedArray> capture_map = | 1259 Handle<FixedArray> capture_map = |
1259 Handle<FixedArray>::cast(maybe_capture_map); | 1260 Handle<FixedArray>::cast(maybe_capture_map); |
1260 Handle<JSObject> groups = ConstructNamedCaptureGroupsObject( | 1261 Handle<JSObject> groups = ConstructNamedCaptureGroupsObject( |
1261 isolate, capture_map, [=](int ix) { return elements->get(ix); }); | 1262 isolate, capture_map, [=](int ix) { return elements->get(ix); }); |
1262 elements->set(cursor++, *groups); | 1263 elements->set(cursor++, *groups); |
1263 } | 1264 } |
1264 | 1265 |
1265 DCHECK_EQ(cursor, argc); | 1266 DCHECK_EQ(cursor, argc); |
1266 builder.Add(*isolate->factory()->NewJSArrayWithElements(elements)); | 1267 builder.Add(*isolate->factory()->NewJSArrayWithElements(elements)); |
1267 } else { | 1268 } else { |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 const int m = match_indices->NumberOfCaptureRegisters() / 2; | 1493 const int m = match_indices->NumberOfCaptureRegisters() / 2; |
1493 | 1494 |
1494 bool has_named_captures = false; | 1495 bool has_named_captures = false; |
1495 Handle<FixedArray> capture_map; | 1496 Handle<FixedArray> capture_map; |
1496 if (m > 1) { | 1497 if (m > 1) { |
1497 // The existence of capture groups implies IRREGEXP kind. | 1498 // The existence of capture groups implies IRREGEXP kind. |
1498 DCHECK_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); | 1499 DCHECK_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); |
1499 | 1500 |
1500 Object* maybe_capture_map = regexp->CaptureNameMap(); | 1501 Object* maybe_capture_map = regexp->CaptureNameMap(); |
1501 if (maybe_capture_map->IsFixedArray()) { | 1502 if (maybe_capture_map->IsFixedArray()) { |
1502 DCHECK(FLAG_harmony_regexp_named_captures); | |
1503 has_named_captures = true; | 1503 has_named_captures = true; |
1504 capture_map = handle(FixedArray::cast(maybe_capture_map)); | 1504 capture_map = handle(FixedArray::cast(maybe_capture_map)); |
1505 } | 1505 } |
1506 } | 1506 } |
1507 | 1507 |
| 1508 DCHECK_IMPLIES(has_named_captures, FLAG_harmony_regexp_named_captures); |
1508 const int argc = has_named_captures ? m + 3 : m + 2; | 1509 const int argc = has_named_captures ? m + 3 : m + 2; |
1509 ScopedVector<Handle<Object>> argv(argc); | 1510 ScopedVector<Handle<Object>> argv(argc); |
1510 | 1511 |
1511 int cursor = 0; | 1512 int cursor = 0; |
1512 for (int j = 0; j < m; j++) { | 1513 for (int j = 0; j < m; j++) { |
1513 bool ok; | 1514 bool ok; |
1514 Handle<String> capture = | 1515 Handle<String> capture = |
1515 RegExpUtils::GenericCaptureGetter(isolate, match_indices, j, &ok); | 1516 RegExpUtils::GenericCaptureGetter(isolate, match_indices, j, &ok); |
1516 if (ok) { | 1517 if (ok) { |
1517 argv[cursor++] = capture; | 1518 argv[cursor++] = capture; |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1846 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1847 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1847 isolate, capture, Object::GetElement(isolate, result, n)); | 1848 isolate, capture, Object::GetElement(isolate, result, n)); |
1848 | 1849 |
1849 if (!capture->IsUndefined(isolate)) { | 1850 if (!capture->IsUndefined(isolate)) { |
1850 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, capture, | 1851 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, capture, |
1851 Object::ToString(isolate, capture)); | 1852 Object::ToString(isolate, capture)); |
1852 } | 1853 } |
1853 captures.push_back(capture); | 1854 captures.push_back(capture); |
1854 } | 1855 } |
1855 | 1856 |
1856 Handle<Object> groups_obj; | 1857 Handle<Object> groups_obj = isolate->factory()->undefined_value(); |
1857 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1858 if (FLAG_harmony_regexp_named_captures) { |
1858 isolate, groups_obj, | 1859 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1859 Object::GetProperty(result, factory->groups_string())); | 1860 isolate, groups_obj, |
| 1861 Object::GetProperty(result, factory->groups_string())); |
| 1862 } |
1860 | 1863 |
1861 const bool has_named_captures = !groups_obj->IsUndefined(isolate); | 1864 const bool has_named_captures = !groups_obj->IsUndefined(isolate); |
| 1865 DCHECK_IMPLIES(has_named_captures, FLAG_harmony_regexp_named_captures); |
1862 | 1866 |
1863 Handle<String> replacement; | 1867 Handle<String> replacement; |
1864 if (functional_replace) { | 1868 if (functional_replace) { |
1865 const int argc = | 1869 const int argc = |
1866 has_named_captures ? captures_length + 3 : captures_length + 2; | 1870 has_named_captures ? captures_length + 3 : captures_length + 2; |
1867 ScopedVector<Handle<Object>> argv(argc); | 1871 ScopedVector<Handle<Object>> argv(argc); |
1868 | 1872 |
1869 int cursor = 0; | 1873 int cursor = 0; |
1870 for (int j = 0; j < captures_length; j++) { | 1874 for (int j = 0; j < captures_length; j++) { |
1871 argv[cursor++] = captures[j]; | 1875 argv[cursor++] = captures[j]; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1938 | 1942 |
1939 RUNTIME_FUNCTION(Runtime_IsRegExp) { | 1943 RUNTIME_FUNCTION(Runtime_IsRegExp) { |
1940 SealHandleScope shs(isolate); | 1944 SealHandleScope shs(isolate); |
1941 DCHECK_EQ(1, args.length()); | 1945 DCHECK_EQ(1, args.length()); |
1942 CONVERT_ARG_CHECKED(Object, obj, 0); | 1946 CONVERT_ARG_CHECKED(Object, obj, 0); |
1943 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); | 1947 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); |
1944 } | 1948 } |
1945 | 1949 |
1946 } // namespace internal | 1950 } // namespace internal |
1947 } // namespace v8 | 1951 } // namespace v8 |
OLD | NEW |