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/conversions-inl.h" | 8 #include "src/conversions-inl.h" |
9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
272 case REPLACEMENT_SUBSTRING: | 272 case REPLACEMENT_SUBSTRING: |
273 case REPLACEMENT_STRING: | 273 case REPLACEMENT_STRING: |
274 builder->AddString(replacement_substrings_[part.data]); | 274 builder->AddString(replacement_substrings_[part.data]); |
275 break; | 275 break; |
276 default: | 276 default: |
277 UNREACHABLE(); | 277 UNREACHABLE(); |
278 } | 278 } |
279 } | 279 } |
280 } | 280 } |
281 | 281 |
282 | |
283 void FindOneByteStringIndices(Vector<const uint8_t> subject, uint8_t pattern, | 282 void FindOneByteStringIndices(Vector<const uint8_t> subject, uint8_t pattern, |
284 ZoneList<int>* indices, unsigned int limit, | 283 List<int>* indices, unsigned int limit) { |
285 Zone* zone) { | |
286 DCHECK(limit > 0); | 284 DCHECK(limit > 0); |
287 // Collect indices of pattern in subject using memchr. | 285 // Collect indices of pattern in subject using memchr. |
288 // Stop after finding at most limit values. | 286 // Stop after finding at most limit values. |
289 const uint8_t* subject_start = subject.start(); | 287 const uint8_t* subject_start = subject.start(); |
290 const uint8_t* subject_end = subject_start + subject.length(); | 288 const uint8_t* subject_end = subject_start + subject.length(); |
291 const uint8_t* pos = subject_start; | 289 const uint8_t* pos = subject_start; |
292 while (limit > 0) { | 290 while (limit > 0) { |
293 pos = reinterpret_cast<const uint8_t*>( | 291 pos = reinterpret_cast<const uint8_t*>( |
294 memchr(pos, pattern, subject_end - pos)); | 292 memchr(pos, pattern, subject_end - pos)); |
295 if (pos == NULL) return; | 293 if (pos == NULL) return; |
296 indices->Add(static_cast<int>(pos - subject_start), zone); | 294 indices->Add(static_cast<int>(pos - subject_start)); |
297 pos++; | 295 pos++; |
298 limit--; | 296 limit--; |
299 } | 297 } |
300 } | 298 } |
301 | 299 |
302 | |
303 void FindTwoByteStringIndices(const Vector<const uc16> subject, uc16 pattern, | 300 void FindTwoByteStringIndices(const Vector<const uc16> subject, uc16 pattern, |
304 ZoneList<int>* indices, unsigned int limit, | 301 List<int>* indices, unsigned int limit) { |
305 Zone* zone) { | |
306 DCHECK(limit > 0); | 302 DCHECK(limit > 0); |
307 const uc16* subject_start = subject.start(); | 303 const uc16* subject_start = subject.start(); |
308 const uc16* subject_end = subject_start + subject.length(); | 304 const uc16* subject_end = subject_start + subject.length(); |
309 for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) { | 305 for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) { |
310 if (*pos == pattern) { | 306 if (*pos == pattern) { |
311 indices->Add(static_cast<int>(pos - subject_start), zone); | 307 indices->Add(static_cast<int>(pos - subject_start)); |
312 limit--; | 308 limit--; |
313 } | 309 } |
314 } | 310 } |
315 } | 311 } |
316 | 312 |
317 | |
318 template <typename SubjectChar, typename PatternChar> | 313 template <typename SubjectChar, typename PatternChar> |
319 void FindStringIndices(Isolate* isolate, Vector<const SubjectChar> subject, | 314 void FindStringIndices(Isolate* isolate, Vector<const SubjectChar> subject, |
320 Vector<const PatternChar> pattern, | 315 Vector<const PatternChar> pattern, List<int>* indices, |
321 ZoneList<int>* indices, unsigned int limit, Zone* zone) { | 316 unsigned int limit) { |
322 DCHECK(limit > 0); | 317 DCHECK(limit > 0); |
323 // Collect indices of pattern in subject. | 318 // Collect indices of pattern in subject. |
324 // Stop after finding at most limit values. | 319 // Stop after finding at most limit values. |
325 int pattern_length = pattern.length(); | 320 int pattern_length = pattern.length(); |
326 int index = 0; | 321 int index = 0; |
327 StringSearch<PatternChar, SubjectChar> search(isolate, pattern); | 322 StringSearch<PatternChar, SubjectChar> search(isolate, pattern); |
328 while (limit > 0) { | 323 while (limit > 0) { |
329 index = search.Search(subject, index); | 324 index = search.Search(subject, index); |
330 if (index < 0) return; | 325 if (index < 0) return; |
331 indices->Add(index, zone); | 326 indices->Add(index); |
332 index += pattern_length; | 327 index += pattern_length; |
333 limit--; | 328 limit--; |
334 } | 329 } |
335 } | 330 } |
336 | 331 |
337 | |
338 void FindStringIndicesDispatch(Isolate* isolate, String* subject, | 332 void FindStringIndicesDispatch(Isolate* isolate, String* subject, |
339 String* pattern, ZoneList<int>* indices, | 333 String* pattern, List<int>* indices, |
340 unsigned int limit, Zone* zone) { | 334 unsigned int limit) { |
341 { | 335 { |
342 DisallowHeapAllocation no_gc; | 336 DisallowHeapAllocation no_gc; |
343 String::FlatContent subject_content = subject->GetFlatContent(); | 337 String::FlatContent subject_content = subject->GetFlatContent(); |
344 String::FlatContent pattern_content = pattern->GetFlatContent(); | 338 String::FlatContent pattern_content = pattern->GetFlatContent(); |
345 DCHECK(subject_content.IsFlat()); | 339 DCHECK(subject_content.IsFlat()); |
346 DCHECK(pattern_content.IsFlat()); | 340 DCHECK(pattern_content.IsFlat()); |
347 if (subject_content.IsOneByte()) { | 341 if (subject_content.IsOneByte()) { |
348 Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector(); | 342 Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector(); |
349 if (pattern_content.IsOneByte()) { | 343 if (pattern_content.IsOneByte()) { |
350 Vector<const uint8_t> pattern_vector = | 344 Vector<const uint8_t> pattern_vector = |
351 pattern_content.ToOneByteVector(); | 345 pattern_content.ToOneByteVector(); |
352 if (pattern_vector.length() == 1) { | 346 if (pattern_vector.length() == 1) { |
353 FindOneByteStringIndices(subject_vector, pattern_vector[0], indices, | 347 FindOneByteStringIndices(subject_vector, pattern_vector[0], indices, |
354 limit, zone); | 348 limit); |
355 } else { | 349 } else { |
356 FindStringIndices(isolate, subject_vector, pattern_vector, indices, | 350 FindStringIndices(isolate, subject_vector, pattern_vector, indices, |
357 limit, zone); | 351 limit); |
358 } | 352 } |
359 } else { | 353 } else { |
360 FindStringIndices(isolate, subject_vector, | 354 FindStringIndices(isolate, subject_vector, |
361 pattern_content.ToUC16Vector(), indices, limit, zone); | 355 pattern_content.ToUC16Vector(), indices, limit); |
362 } | 356 } |
363 } else { | 357 } else { |
364 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); | 358 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); |
365 if (pattern_content.IsOneByte()) { | 359 if (pattern_content.IsOneByte()) { |
366 Vector<const uint8_t> pattern_vector = | 360 Vector<const uint8_t> pattern_vector = |
367 pattern_content.ToOneByteVector(); | 361 pattern_content.ToOneByteVector(); |
368 if (pattern_vector.length() == 1) { | 362 if (pattern_vector.length() == 1) { |
369 FindTwoByteStringIndices(subject_vector, pattern_vector[0], indices, | 363 FindTwoByteStringIndices(subject_vector, pattern_vector[0], indices, |
370 limit, zone); | 364 limit); |
371 } else { | 365 } else { |
372 FindStringIndices(isolate, subject_vector, pattern_vector, indices, | 366 FindStringIndices(isolate, subject_vector, pattern_vector, indices, |
373 limit, zone); | 367 limit); |
374 } | 368 } |
375 } else { | 369 } else { |
376 Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector(); | 370 Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector(); |
377 if (pattern_vector.length() == 1) { | 371 if (pattern_vector.length() == 1) { |
378 FindTwoByteStringIndices(subject_vector, pattern_vector[0], indices, | 372 FindTwoByteStringIndices(subject_vector, pattern_vector[0], indices, |
379 limit, zone); | 373 limit); |
380 } else { | 374 } else { |
381 FindStringIndices(isolate, subject_vector, pattern_vector, indices, | 375 FindStringIndices(isolate, subject_vector, pattern_vector, indices, |
382 limit, zone); | 376 limit); |
383 } | 377 } |
384 } | 378 } |
385 } | 379 } |
386 } | 380 } |
387 } | 381 } |
388 | 382 |
383 namespace { | |
384 static List<int>* GetRewindedRegexpIndicesList(Isolate* isolate) { | |
ahaas
2016/10/06 08:43:19
putting a function into an anonymous namespace is
| |
385 List<int>* list = isolate->regexp_indices(); | |
386 list->Rewind(0); | |
387 return list; | |
388 } | |
389 | |
390 static void TruncateRegexpIndicesList(Isolate* isolate) { | |
391 // Same size as smallest zone segment, preserving behavior from the runtime | |
392 // zone. | |
393 static const size_t kMaxRegexpIndicesListCapacity = 8 * KB; | |
394 if (isolate->regexp_indices()->capacity() > kMaxRegexpIndicesListCapacity) { | |
395 isolate->regexp_indices()->Clear(); // Throw away backing storage | |
396 } | |
397 } | |
398 } // namespace | |
399 | |
389 template <typename ResultSeqString> | 400 template <typename ResultSeqString> |
390 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString( | 401 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString( |
391 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> pattern_regexp, | 402 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> pattern_regexp, |
392 Handle<String> replacement, Handle<JSObject> last_match_info) { | 403 Handle<String> replacement, Handle<JSObject> last_match_info) { |
393 DCHECK(subject->IsFlat()); | 404 DCHECK(subject->IsFlat()); |
394 DCHECK(replacement->IsFlat()); | 405 DCHECK(replacement->IsFlat()); |
395 | 406 |
396 ZoneScope zone_scope(isolate->runtime_zone()); | 407 List<int>* indices = GetRewindedRegexpIndicesList(isolate); |
397 ZoneList<int> indices(8, zone_scope.zone()); | 408 |
398 DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag()); | 409 DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag()); |
399 String* pattern = | 410 String* pattern = |
400 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); | 411 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); |
401 int subject_len = subject->length(); | 412 int subject_len = subject->length(); |
402 int pattern_len = pattern->length(); | 413 int pattern_len = pattern->length(); |
403 int replacement_len = replacement->length(); | 414 int replacement_len = replacement->length(); |
404 | 415 |
405 FindStringIndicesDispatch(isolate, *subject, pattern, &indices, 0xffffffff, | 416 FindStringIndicesDispatch(isolate, *subject, pattern, indices, 0xffffffff); |
406 zone_scope.zone()); | |
407 | 417 |
408 int matches = indices.length(); | 418 int matches = indices->length(); |
409 if (matches == 0) return *subject; | 419 if (matches == 0) return *subject; |
410 | 420 |
411 // Detect integer overflow. | 421 // Detect integer overflow. |
412 int64_t result_len_64 = (static_cast<int64_t>(replacement_len) - | 422 int64_t result_len_64 = (static_cast<int64_t>(replacement_len) - |
413 static_cast<int64_t>(pattern_len)) * | 423 static_cast<int64_t>(pattern_len)) * |
414 static_cast<int64_t>(matches) + | 424 static_cast<int64_t>(matches) + |
415 static_cast<int64_t>(subject_len); | 425 static_cast<int64_t>(subject_len); |
416 int result_len; | 426 int result_len; |
417 if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) { | 427 if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) { |
418 STATIC_ASSERT(String::kMaxLength < kMaxInt); | 428 STATIC_ASSERT(String::kMaxLength < kMaxInt); |
(...skipping 10 matching lines...) Expand all Loading... | |
429 maybe_res = isolate->factory()->NewRawOneByteString(result_len); | 439 maybe_res = isolate->factory()->NewRawOneByteString(result_len); |
430 } else { | 440 } else { |
431 maybe_res = isolate->factory()->NewRawTwoByteString(result_len); | 441 maybe_res = isolate->factory()->NewRawTwoByteString(result_len); |
432 } | 442 } |
433 Handle<SeqString> untyped_res; | 443 Handle<SeqString> untyped_res; |
434 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res); | 444 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res); |
435 Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res); | 445 Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res); |
436 | 446 |
437 for (int i = 0; i < matches; i++) { | 447 for (int i = 0; i < matches; i++) { |
438 // Copy non-matched subject content. | 448 // Copy non-matched subject content. |
439 if (subject_pos < indices.at(i)) { | 449 if (subject_pos < indices->at(i)) { |
440 String::WriteToFlat(*subject, result->GetChars() + result_pos, | 450 String::WriteToFlat(*subject, result->GetChars() + result_pos, |
441 subject_pos, indices.at(i)); | 451 subject_pos, indices->at(i)); |
442 result_pos += indices.at(i) - subject_pos; | 452 result_pos += indices->at(i) - subject_pos; |
443 } | 453 } |
444 | 454 |
445 // Replace match. | 455 // Replace match. |
446 if (replacement_len > 0) { | 456 if (replacement_len > 0) { |
447 String::WriteToFlat(*replacement, result->GetChars() + result_pos, 0, | 457 String::WriteToFlat(*replacement, result->GetChars() + result_pos, 0, |
448 replacement_len); | 458 replacement_len); |
449 result_pos += replacement_len; | 459 result_pos += replacement_len; |
450 } | 460 } |
451 | 461 |
452 subject_pos = indices.at(i) + pattern_len; | 462 subject_pos = indices->at(i) + pattern_len; |
453 } | 463 } |
454 // Add remaining subject content at the end. | 464 // Add remaining subject content at the end. |
455 if (subject_pos < subject_len) { | 465 if (subject_pos < subject_len) { |
456 String::WriteToFlat(*subject, result->GetChars() + result_pos, subject_pos, | 466 String::WriteToFlat(*subject, result->GetChars() + result_pos, subject_pos, |
457 subject_len); | 467 subject_len); |
458 } | 468 } |
459 | 469 |
460 int32_t match_indices[] = {indices.at(matches - 1), | 470 int32_t match_indices[] = {indices->at(matches - 1), |
461 indices.at(matches - 1) + pattern_len}; | 471 indices->at(matches - 1) + pattern_len}; |
462 RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices); | 472 RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices); |
463 | 473 |
474 TruncateRegexpIndicesList(isolate); | |
475 | |
464 return *result; | 476 return *result; |
465 } | 477 } |
466 | 478 |
467 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString( | 479 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString( |
468 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp, | 480 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp, |
469 Handle<String> replacement, Handle<JSObject> last_match_info) { | 481 Handle<String> replacement, Handle<JSObject> last_match_info) { |
470 DCHECK(subject->IsFlat()); | 482 DCHECK(subject->IsFlat()); |
471 DCHECK(replacement->IsFlat()); | 483 DCHECK(replacement->IsFlat()); |
472 | 484 |
473 int capture_count = regexp->CaptureCount(); | 485 int capture_count = regexp->CaptureCount(); |
474 int subject_length = subject->length(); | 486 int subject_length = subject->length(); |
475 | 487 |
476 // CompiledReplacement uses zone allocation. | 488 // CompiledReplacement uses zone allocation. |
477 ZoneScope zone_scope(isolate->runtime_zone()); | 489 Zone zone(isolate->allocator()); |
478 CompiledReplacement compiled_replacement(zone_scope.zone()); | 490 CompiledReplacement compiled_replacement(&zone); |
479 bool simple_replace = | 491 bool simple_replace = |
480 compiled_replacement.Compile(replacement, capture_count, subject_length); | 492 compiled_replacement.Compile(replacement, capture_count, subject_length); |
481 | 493 |
482 // Shortcut for simple non-regexp global replacements | 494 // Shortcut for simple non-regexp global replacements |
483 if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) { | 495 if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) { |
484 if (subject->HasOnlyOneByteChars() && replacement->HasOnlyOneByteChars()) { | 496 if (subject->HasOnlyOneByteChars() && replacement->HasOnlyOneByteChars()) { |
485 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( | 497 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( |
486 isolate, subject, regexp, replacement, last_match_info); | 498 isolate, subject, regexp, replacement, last_match_info); |
487 } else { | 499 } else { |
488 return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>( | 500 return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>( |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
702 } | 714 } |
703 } | 715 } |
704 | 716 |
705 // The limit can be very large (0xffffffffu), but since the pattern | 717 // The limit can be very large (0xffffffffu), but since the pattern |
706 // isn't empty, we can never create more parts than ~half the length | 718 // isn't empty, we can never create more parts than ~half the length |
707 // of the subject. | 719 // of the subject. |
708 | 720 |
709 subject = String::Flatten(subject); | 721 subject = String::Flatten(subject); |
710 pattern = String::Flatten(pattern); | 722 pattern = String::Flatten(pattern); |
711 | 723 |
712 static const int kMaxInitialListCapacity = 16; | 724 List<int>* indices = GetRewindedRegexpIndicesList(isolate); |
713 | 725 |
714 ZoneScope zone_scope(isolate->runtime_zone()); | 726 FindStringIndicesDispatch(isolate, *subject, *pattern, indices, limit); |
715 | 727 |
716 // Find (up to limit) indices of separator and end-of-string in subject | 728 if (static_cast<uint32_t>(indices->length()) < limit) { |
717 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); | 729 indices->Add(subject_length); |
718 ZoneList<int> indices(initial_capacity, zone_scope.zone()); | |
719 | |
720 FindStringIndicesDispatch(isolate, *subject, *pattern, &indices, limit, | |
721 zone_scope.zone()); | |
722 | |
723 if (static_cast<uint32_t>(indices.length()) < limit) { | |
724 indices.Add(subject_length, zone_scope.zone()); | |
725 } | 730 } |
726 | 731 |
727 // The list indices now contains the end of each part to create. | 732 // The list indices now contains the end of each part to create. |
728 | 733 |
729 // Create JSArray of substrings separated by separator. | 734 // Create JSArray of substrings separated by separator. |
730 int part_count = indices.length(); | 735 int part_count = indices->length(); |
731 | 736 |
732 Handle<JSArray> result = | 737 Handle<JSArray> result = |
733 isolate->factory()->NewJSArray(FAST_ELEMENTS, part_count, part_count, | 738 isolate->factory()->NewJSArray(FAST_ELEMENTS, part_count, part_count, |
734 INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); | 739 INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); |
735 | 740 |
736 DCHECK(result->HasFastObjectElements()); | 741 DCHECK(result->HasFastObjectElements()); |
737 | 742 |
738 Handle<FixedArray> elements(FixedArray::cast(result->elements())); | 743 Handle<FixedArray> elements(FixedArray::cast(result->elements())); |
739 | 744 |
740 if (part_count == 1 && indices.at(0) == subject_length) { | 745 if (part_count == 1 && indices->at(0) == subject_length) { |
741 elements->set(0, *subject); | 746 elements->set(0, *subject); |
742 } else { | 747 } else { |
743 int part_start = 0; | 748 int part_start = 0; |
744 FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < part_count, i++, { | 749 FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < part_count, i++, { |
745 int part_end = indices.at(i); | 750 int part_end = indices->at(i); |
746 Handle<String> substring = | 751 Handle<String> substring = |
747 isolate->factory()->NewProperSubString(subject, part_start, part_end); | 752 isolate->factory()->NewProperSubString(subject, part_start, part_end); |
748 elements->set(i, *substring); | 753 elements->set(i, *substring); |
749 part_start = part_end + pattern_length; | 754 part_start = part_end + pattern_length; |
750 }); | 755 }); |
751 } | 756 } |
752 | 757 |
753 if (limit == 0xffffffffu) { | 758 if (limit == 0xffffffffu) { |
754 if (result->HasFastObjectElements()) { | 759 if (result->HasFastObjectElements()) { |
755 RegExpResultsCache::Enter(isolate, subject, pattern, elements, | 760 RegExpResultsCache::Enter(isolate, subject, pattern, elements, |
756 isolate->factory()->empty_fixed_array(), | 761 isolate->factory()->empty_fixed_array(), |
757 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS); | 762 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS); |
758 } | 763 } |
759 } | 764 } |
760 | 765 |
766 TruncateRegexpIndicesList(isolate); | |
767 | |
761 return *result; | 768 return *result; |
762 } | 769 } |
763 | 770 |
764 | 771 |
765 RUNTIME_FUNCTION(Runtime_RegExpExec) { | 772 RUNTIME_FUNCTION(Runtime_RegExpExec) { |
766 HandleScope scope(isolate); | 773 HandleScope scope(isolate); |
767 DCHECK(args.length() == 4); | 774 DCHECK(args.length() == 4); |
768 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); | 775 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); |
769 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); | 776 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); |
770 CONVERT_INT32_ARG_CHECKED(index, 2); | 777 CONVERT_INT32_ARG_CHECKED(index, 2); |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1013 | 1020 |
1014 | 1021 |
1015 RUNTIME_FUNCTION(Runtime_IsRegExp) { | 1022 RUNTIME_FUNCTION(Runtime_IsRegExp) { |
1016 SealHandleScope shs(isolate); | 1023 SealHandleScope shs(isolate); |
1017 DCHECK(args.length() == 1); | 1024 DCHECK(args.length() == 1); |
1018 CONVERT_ARG_CHECKED(Object, obj, 0); | 1025 CONVERT_ARG_CHECKED(Object, obj, 0); |
1019 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); | 1026 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); |
1020 } | 1027 } |
1021 } // namespace internal | 1028 } // namespace internal |
1022 } // namespace v8 | 1029 } // namespace v8 |
OLD | NEW |