| 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 |