Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(410)

Side by Side Diff: src/builtins/builtins-regexp.cc

Issue 2498073002: [refactoring] Split CodeAssemblerState out of CodeAssembler (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/builtins/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/regexp/jsregexp.h" 9 #include "src/regexp/jsregexp.h"
10 #include "src/regexp/regexp-utils.h" 10 #include "src/regexp/regexp-utils.h"
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 } 457 }
458 458
459 a->Bind(&out); 459 a->Bind(&out);
460 return var_result.value(); 460 return var_result.value();
461 } 461 }
462 462
463 } // namespace 463 } // namespace
464 464
465 // ES#sec-regexp.prototype.exec 465 // ES#sec-regexp.prototype.exec
466 // RegExp.prototype.exec ( string ) 466 // RegExp.prototype.exec ( string )
467 void Builtins::Generate_RegExpPrototypeExec(CodeStubAssembler* a) { 467 void Builtins::Generate_RegExpPrototypeExec(
468 compiler::CodeAssemblerState* state) {
468 typedef compiler::Node Node; 469 typedef compiler::Node Node;
470 CodeStubAssembler a(state);
469 471
470 Node* const maybe_receiver = a->Parameter(0); 472 Node* const maybe_receiver = a.Parameter(0);
471 Node* const maybe_string = a->Parameter(1); 473 Node* const maybe_string = a.Parameter(1);
472 Node* const context = a->Parameter(4); 474 Node* const context = a.Parameter(4);
473 475
474 Node* const result = 476 Node* const result =
475 RegExpPrototypeExecInternal(a, context, maybe_receiver, maybe_string); 477 RegExpPrototypeExecInternal(&a, context, maybe_receiver, maybe_string);
476 a->Return(result); 478 a.Return(result);
477 } 479 }
478 480
479 namespace { 481 namespace {
480 482
481 compiler::Node* ThrowIfNotJSReceiver(CodeStubAssembler* a, Isolate* isolate, 483 compiler::Node* ThrowIfNotJSReceiver(CodeStubAssembler* a, Isolate* isolate,
482 compiler::Node* context, 484 compiler::Node* context,
483 compiler::Node* value, 485 compiler::Node* value,
484 MessageTemplate::Template msg_template, 486 MessageTemplate::Template msg_template,
485 char const* method_name) { 487 char const* method_name) {
486 typedef compiler::Node Node; 488 typedef compiler::Node Node;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 a->WordEqual(proto_map, initial_proto_initial_map); 563 a->WordEqual(proto_map, initial_proto_initial_map);
562 564
563 // TODO(ishell): Update this check once map changes for constant field 565 // TODO(ishell): Update this check once map changes for constant field
564 // tracking are landing. 566 // tracking are landing.
565 567
566 a->Branch(proto_has_initialmap, if_isunmodified, if_ismodified); 568 a->Branch(proto_has_initialmap, if_isunmodified, if_ismodified);
567 } 569 }
568 570
569 } // namespace 571 } // namespace
570 572
571 void Builtins::Generate_RegExpPrototypeFlagsGetter(CodeStubAssembler* a) { 573 void Builtins::Generate_RegExpPrototypeFlagsGetter(
574 compiler::CodeAssemblerState* state) {
572 typedef CodeStubAssembler::Variable Variable; 575 typedef CodeStubAssembler::Variable Variable;
573 typedef CodeStubAssembler::Label Label; 576 typedef CodeStubAssembler::Label Label;
574 typedef compiler::Node Node; 577 typedef compiler::Node Node;
578 CodeStubAssembler a(state);
575 579
576 Node* const receiver = a->Parameter(0); 580 Node* const receiver = a.Parameter(0);
577 Node* const context = a->Parameter(3); 581 Node* const context = a.Parameter(3);
578 582
579 Isolate* isolate = a->isolate(); 583 Isolate* isolate = a.isolate();
580 Node* const int_zero = a->IntPtrConstant(0); 584 Node* const int_zero = a.IntPtrConstant(0);
581 Node* const int_one = a->IntPtrConstant(1); 585 Node* const int_one = a.IntPtrConstant(1);
582 586
583 Node* const map = ThrowIfNotJSReceiver(a, isolate, context, receiver, 587 Node* const map = ThrowIfNotJSReceiver(&a, isolate, context, receiver,
584 MessageTemplate::kRegExpNonObject, 588 MessageTemplate::kRegExpNonObject,
585 "RegExp.prototype.flags"); 589 "RegExp.prototype.flags");
586 590
587 Variable var_length(a, MachineType::PointerRepresentation()); 591 Variable var_length(&a, MachineType::PointerRepresentation());
588 Variable var_flags(a, MachineType::PointerRepresentation()); 592 Variable var_flags(&a, MachineType::PointerRepresentation());
589 593
590 // First, count the number of characters we will need and check which flags 594 // First, count the number of characters we will need and check which flags
591 // are set. 595 // are set.
592 596
593 var_length.Bind(int_zero); 597 var_length.Bind(int_zero);
594 598
595 Label if_isunmodifiedjsregexp(a), 599 Label if_isunmodifiedjsregexp(&a),
596 if_isnotunmodifiedjsregexp(a, Label::kDeferred); 600 if_isnotunmodifiedjsregexp(&a, Label::kDeferred);
597 a->Branch(IsInitialRegExpMap(a, context, map), &if_isunmodifiedjsregexp, 601 a.Branch(IsInitialRegExpMap(&a, context, map), &if_isunmodifiedjsregexp,
598 &if_isnotunmodifiedjsregexp); 602 &if_isnotunmodifiedjsregexp);
599 603
600 Label construct_string(a); 604 Label construct_string(&a);
601 a->Bind(&if_isunmodifiedjsregexp); 605 a.Bind(&if_isunmodifiedjsregexp);
602 { 606 {
603 // Refer to JSRegExp's flag property on the fast-path. 607 // Refer to JSRegExp's flag property on the fast-path.
604 Node* const flags_smi = 608 Node* const flags_smi = a.LoadObjectField(receiver, JSRegExp::kFlagsOffset);
605 a->LoadObjectField(receiver, JSRegExp::kFlagsOffset); 609 Node* const flags_intptr = a.SmiUntag(flags_smi);
606 Node* const flags_intptr = a->SmiUntag(flags_smi);
607 var_flags.Bind(flags_intptr); 610 var_flags.Bind(flags_intptr);
608 611
609 Label label_global(a), label_ignorecase(a), label_multiline(a), 612 Label label_global(&a), label_ignorecase(&a), label_multiline(&a),
610 label_unicode(a), label_sticky(a); 613 label_unicode(&a), label_sticky(&a);
611 614
612 #define CASE_FOR_FLAG(FLAG, LABEL, NEXT_LABEL) \ 615 #define CASE_FOR_FLAG(FLAG, LABEL, NEXT_LABEL) \
613 do { \ 616 do { \
614 a->Bind(&LABEL); \ 617 a.Bind(&LABEL); \
615 Node* const mask = a->IntPtrConstant(FLAG); \ 618 Node* const mask = a.IntPtrConstant(FLAG); \
616 a->GotoIf(a->WordEqual(a->WordAnd(flags_intptr, mask), int_zero), \ 619 a.GotoIf(a.WordEqual(a.WordAnd(flags_intptr, mask), int_zero), \
617 &NEXT_LABEL); \ 620 &NEXT_LABEL); \
618 var_length.Bind(a->IntPtrAdd(var_length.value(), int_one)); \ 621 var_length.Bind(a.IntPtrAdd(var_length.value(), int_one)); \
619 a->Goto(&NEXT_LABEL); \ 622 a.Goto(&NEXT_LABEL); \
620 } while (false) 623 } while (false)
621 624
622 a->Goto(&label_global); 625 a.Goto(&label_global);
623 CASE_FOR_FLAG(JSRegExp::kGlobal, label_global, label_ignorecase); 626 CASE_FOR_FLAG(JSRegExp::kGlobal, label_global, label_ignorecase);
624 CASE_FOR_FLAG(JSRegExp::kIgnoreCase, label_ignorecase, label_multiline); 627 CASE_FOR_FLAG(JSRegExp::kIgnoreCase, label_ignorecase, label_multiline);
625 CASE_FOR_FLAG(JSRegExp::kMultiline, label_multiline, label_unicode); 628 CASE_FOR_FLAG(JSRegExp::kMultiline, label_multiline, label_unicode);
626 CASE_FOR_FLAG(JSRegExp::kUnicode, label_unicode, label_sticky); 629 CASE_FOR_FLAG(JSRegExp::kUnicode, label_unicode, label_sticky);
627 CASE_FOR_FLAG(JSRegExp::kSticky, label_sticky, construct_string); 630 CASE_FOR_FLAG(JSRegExp::kSticky, label_sticky, construct_string);
628 #undef CASE_FOR_FLAG 631 #undef CASE_FOR_FLAG
629 } 632 }
630 633
631 a->Bind(&if_isnotunmodifiedjsregexp); 634 a.Bind(&if_isnotunmodifiedjsregexp);
632 { 635 {
633 // Fall back to GetProperty stub on the slow-path. 636 // Fall back to GetProperty stub on the slow-path.
634 var_flags.Bind(int_zero); 637 var_flags.Bind(int_zero);
635 638
636 Callable getproperty_callable = CodeFactory::GetProperty(a->isolate()); 639 Callable getproperty_callable = CodeFactory::GetProperty(a.isolate());
637 Label label_global(a), label_ignorecase(a), label_multiline(a), 640 Label label_global(&a), label_ignorecase(&a), label_multiline(&a),
638 label_unicode(a), label_sticky(a); 641 label_unicode(&a), label_sticky(&a);
639 642
640 #define CASE_FOR_FLAG(NAME, FLAG, LABEL, NEXT_LABEL) \ 643 #define CASE_FOR_FLAG(NAME, FLAG, LABEL, NEXT_LABEL) \
641 do { \ 644 do { \
642 a->Bind(&LABEL); \ 645 a.Bind(&LABEL); \
643 Node* const name = \ 646 Node* const name = \
644 a->HeapConstant(isolate->factory()->NewStringFromAsciiChecked(NAME)); \ 647 a.HeapConstant(isolate->factory()->NewStringFromAsciiChecked(NAME)); \
645 Node* const flag = \ 648 Node* const flag = \
646 a->CallStub(getproperty_callable, context, receiver, name); \ 649 a.CallStub(getproperty_callable, context, receiver, name); \
647 Label if_isflagset(a); \ 650 Label if_isflagset(&a); \
648 a->BranchIfToBooleanIsTrue(flag, &if_isflagset, &NEXT_LABEL); \ 651 a.BranchIfToBooleanIsTrue(flag, &if_isflagset, &NEXT_LABEL); \
649 a->Bind(&if_isflagset); \ 652 a.Bind(&if_isflagset); \
650 var_length.Bind(a->IntPtrAdd(var_length.value(), int_one)); \ 653 var_length.Bind(a.IntPtrAdd(var_length.value(), int_one)); \
651 var_flags.Bind(a->WordOr(var_flags.value(), a->IntPtrConstant(FLAG))); \ 654 var_flags.Bind(a.WordOr(var_flags.value(), a.IntPtrConstant(FLAG))); \
652 a->Goto(&NEXT_LABEL); \ 655 a.Goto(&NEXT_LABEL); \
653 } while (false) 656 } while (false)
654 657
655 a->Goto(&label_global); 658 a.Goto(&label_global);
656 CASE_FOR_FLAG("global", JSRegExp::kGlobal, label_global, label_ignorecase); 659 CASE_FOR_FLAG("global", JSRegExp::kGlobal, label_global, label_ignorecase);
657 CASE_FOR_FLAG("ignoreCase", JSRegExp::kIgnoreCase, label_ignorecase, 660 CASE_FOR_FLAG("ignoreCase", JSRegExp::kIgnoreCase, label_ignorecase,
658 label_multiline); 661 label_multiline);
659 CASE_FOR_FLAG("multiline", JSRegExp::kMultiline, label_multiline, 662 CASE_FOR_FLAG("multiline", JSRegExp::kMultiline, label_multiline,
660 label_unicode); 663 label_unicode);
661 CASE_FOR_FLAG("unicode", JSRegExp::kUnicode, label_unicode, label_sticky); 664 CASE_FOR_FLAG("unicode", JSRegExp::kUnicode, label_unicode, label_sticky);
662 CASE_FOR_FLAG("sticky", JSRegExp::kSticky, label_sticky, construct_string); 665 CASE_FOR_FLAG("sticky", JSRegExp::kSticky, label_sticky, construct_string);
663 #undef CASE_FOR_FLAG 666 #undef CASE_FOR_FLAG
664 } 667 }
665 668
666 // Allocate a string of the required length and fill it with the corresponding 669 // Allocate a string of the required length and fill it with the corresponding
667 // char for each set flag. 670 // char for each set flag.
668 671
669 a->Bind(&construct_string); 672 a.Bind(&construct_string);
670 { 673 {
671 Node* const result = 674 Node* const result =
672 a->AllocateSeqOneByteString(context, var_length.value()); 675 a.AllocateSeqOneByteString(context, var_length.value());
673 Node* const flags_intptr = var_flags.value(); 676 Node* const flags_intptr = var_flags.value();
674 677
675 Variable var_offset(a, MachineType::PointerRepresentation()); 678 Variable var_offset(&a, MachineType::PointerRepresentation());
676 var_offset.Bind( 679 var_offset.Bind(
677 a->IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 680 a.IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag));
678 681
679 Label label_global(a), label_ignorecase(a), label_multiline(a), 682 Label label_global(&a), label_ignorecase(&a), label_multiline(&a),
680 label_unicode(a), label_sticky(a), out(a); 683 label_unicode(&a), label_sticky(&a), out(&a);
681 684
682 #define CASE_FOR_FLAG(FLAG, CHAR, LABEL, NEXT_LABEL) \ 685 #define CASE_FOR_FLAG(FLAG, CHAR, LABEL, NEXT_LABEL) \
683 do { \ 686 do { \
684 a->Bind(&LABEL); \ 687 a.Bind(&LABEL); \
685 Node* const mask = a->IntPtrConstant(FLAG); \ 688 Node* const mask = a.IntPtrConstant(FLAG); \
686 a->GotoIf(a->WordEqual(a->WordAnd(flags_intptr, mask), int_zero), \ 689 a.GotoIf(a.WordEqual(a.WordAnd(flags_intptr, mask), int_zero), \
687 &NEXT_LABEL); \ 690 &NEXT_LABEL); \
688 Node* const value = a->IntPtrConstant(CHAR); \ 691 Node* const value = a.IntPtrConstant(CHAR); \
689 a->StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \ 692 a.StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \
690 var_offset.value(), value); \ 693 var_offset.value(), value); \
691 var_offset.Bind(a->IntPtrAdd(var_offset.value(), int_one)); \ 694 var_offset.Bind(a.IntPtrAdd(var_offset.value(), int_one)); \
692 a->Goto(&NEXT_LABEL); \ 695 a.Goto(&NEXT_LABEL); \
693 } while (false) 696 } while (false)
694 697
695 a->Goto(&label_global); 698 a.Goto(&label_global);
696 CASE_FOR_FLAG(JSRegExp::kGlobal, 'g', label_global, label_ignorecase); 699 CASE_FOR_FLAG(JSRegExp::kGlobal, 'g', label_global, label_ignorecase);
697 CASE_FOR_FLAG(JSRegExp::kIgnoreCase, 'i', label_ignorecase, 700 CASE_FOR_FLAG(JSRegExp::kIgnoreCase, 'i', label_ignorecase,
698 label_multiline); 701 label_multiline);
699 CASE_FOR_FLAG(JSRegExp::kMultiline, 'm', label_multiline, label_unicode); 702 CASE_FOR_FLAG(JSRegExp::kMultiline, 'm', label_multiline, label_unicode);
700 CASE_FOR_FLAG(JSRegExp::kUnicode, 'u', label_unicode, label_sticky); 703 CASE_FOR_FLAG(JSRegExp::kUnicode, 'u', label_unicode, label_sticky);
701 CASE_FOR_FLAG(JSRegExp::kSticky, 'y', label_sticky, out); 704 CASE_FOR_FLAG(JSRegExp::kSticky, 'y', label_sticky, out);
702 #undef CASE_FOR_FLAG 705 #undef CASE_FOR_FLAG
703 706
704 a->Bind(&out); 707 a.Bind(&out);
705 a->Return(result); 708 a.Return(result);
706 } 709 }
707 } 710 }
708 711
709 // ES6 21.2.5.10. 712 // ES6 21.2.5.10.
710 BUILTIN(RegExpPrototypeSourceGetter) { 713 BUILTIN(RegExpPrototypeSourceGetter) {
711 HandleScope scope(isolate); 714 HandleScope scope(isolate);
712 715
713 Handle<Object> recv = args.receiver(); 716 Handle<Object> recv = args.receiver();
714 if (!recv->IsJSRegExp()) { 717 if (!recv->IsJSRegExp()) {
715 Handle<JSFunction> regexp_fun = isolate->regexp_function(); 718 Handle<JSFunction> regexp_fun = isolate->regexp_function();
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 a->CallRuntime(Runtime::kThrowTypeError, context, message_id, 848 a->CallRuntime(Runtime::kThrowTypeError, context, message_id,
846 method_name_str); 849 method_name_str);
847 a->Return(a->UndefinedConstant()); // Never reached. 850 a->Return(a->UndefinedConstant()); // Never reached.
848 } 851 }
849 } 852 }
850 } 853 }
851 854
852 } // namespace 855 } // namespace
853 856
854 // ES6 21.2.5.4. 857 // ES6 21.2.5.4.
855 void Builtins::Generate_RegExpPrototypeGlobalGetter(CodeStubAssembler* a) { 858 void Builtins::Generate_RegExpPrototypeGlobalGetter(
856 Generate_FlagGetter(a, JSRegExp::kGlobal, 859 compiler::CodeAssemblerState* state) {
860 CodeStubAssembler a(state);
861 Generate_FlagGetter(&a, JSRegExp::kGlobal,
857 v8::Isolate::kRegExpPrototypeOldFlagGetter, 862 v8::Isolate::kRegExpPrototypeOldFlagGetter,
858 "RegExp.prototype.global"); 863 "RegExp.prototype.global");
859 } 864 }
860 865
861 // ES6 21.2.5.5. 866 // ES6 21.2.5.5.
862 void Builtins::Generate_RegExpPrototypeIgnoreCaseGetter(CodeStubAssembler* a) { 867 void Builtins::Generate_RegExpPrototypeIgnoreCaseGetter(
863 Generate_FlagGetter(a, JSRegExp::kIgnoreCase, 868 compiler::CodeAssemblerState* state) {
869 CodeStubAssembler a(state);
870 Generate_FlagGetter(&a, JSRegExp::kIgnoreCase,
864 v8::Isolate::kRegExpPrototypeOldFlagGetter, 871 v8::Isolate::kRegExpPrototypeOldFlagGetter,
865 "RegExp.prototype.ignoreCase"); 872 "RegExp.prototype.ignoreCase");
866 } 873 }
867 874
868 // ES6 21.2.5.7. 875 // ES6 21.2.5.7.
869 void Builtins::Generate_RegExpPrototypeMultilineGetter(CodeStubAssembler* a) { 876 void Builtins::Generate_RegExpPrototypeMultilineGetter(
870 Generate_FlagGetter(a, JSRegExp::kMultiline, 877 compiler::CodeAssemblerState* state) {
878 CodeStubAssembler a(state);
879 Generate_FlagGetter(&a, JSRegExp::kMultiline,
871 v8::Isolate::kRegExpPrototypeOldFlagGetter, 880 v8::Isolate::kRegExpPrototypeOldFlagGetter,
872 "RegExp.prototype.multiline"); 881 "RegExp.prototype.multiline");
873 } 882 }
874 883
875 // ES6 21.2.5.12. 884 // ES6 21.2.5.12.
876 void Builtins::Generate_RegExpPrototypeStickyGetter(CodeStubAssembler* a) { 885 void Builtins::Generate_RegExpPrototypeStickyGetter(
877 Generate_FlagGetter(a, JSRegExp::kSticky, 886 compiler::CodeAssemblerState* state) {
887 CodeStubAssembler a(state);
888 Generate_FlagGetter(&a, JSRegExp::kSticky,
878 v8::Isolate::kRegExpPrototypeStickyGetter, 889 v8::Isolate::kRegExpPrototypeStickyGetter,
879 "RegExp.prototype.sticky"); 890 "RegExp.prototype.sticky");
880 } 891 }
881 892
882 // ES6 21.2.5.15. 893 // ES6 21.2.5.15.
883 void Builtins::Generate_RegExpPrototypeUnicodeGetter(CodeStubAssembler* a) { 894 void Builtins::Generate_RegExpPrototypeUnicodeGetter(
884 Generate_FlagGetter(a, JSRegExp::kUnicode, 895 compiler::CodeAssemblerState* state) {
896 CodeStubAssembler a(state);
897 Generate_FlagGetter(&a, JSRegExp::kUnicode,
885 v8::Isolate::kRegExpPrototypeUnicodeGetter, 898 v8::Isolate::kRegExpPrototypeUnicodeGetter,
886 "RegExp.prototype.unicode"); 899 "RegExp.prototype.unicode");
887 } 900 }
888 901
889 // The properties $1..$9 are the first nine capturing substrings of the last 902 // The properties $1..$9 are the first nine capturing substrings of the last
890 // successful match, or ''. The function RegExpMakeCaptureGetter will be 903 // successful match, or ''. The function RegExpMakeCaptureGetter will be
891 // called with indices from 1 to 9. 904 // called with indices from 1 to 9.
892 #define DEFINE_CAPTURE_GETTER(i) \ 905 #define DEFINE_CAPTURE_GETTER(i) \
893 BUILTIN(RegExpCapture##i##Getter) { \ 906 BUILTIN(RegExpCapture##i##Getter) { \
894 HandleScope scope(isolate); \ 907 HandleScope scope(isolate); \
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 } 1050 }
1038 1051
1039 a->Bind(&out); 1052 a->Bind(&out);
1040 return var_result.value(); 1053 return var_result.value();
1041 } 1054 }
1042 1055
1043 } // namespace 1056 } // namespace
1044 1057
1045 // ES#sec-regexp.prototype.test 1058 // ES#sec-regexp.prototype.test
1046 // RegExp.prototype.test ( S ) 1059 // RegExp.prototype.test ( S )
1047 void Builtins::Generate_RegExpPrototypeTest(CodeStubAssembler* a) { 1060 void Builtins::Generate_RegExpPrototypeTest(
1061 compiler::CodeAssemblerState* state) {
1048 typedef compiler::Node Node; 1062 typedef compiler::Node Node;
1063 CodeStubAssembler a(state);
1049 1064
1050 Isolate* const isolate = a->isolate(); 1065 Isolate* const isolate = a.isolate();
1051 1066
1052 Node* const maybe_receiver = a->Parameter(0); 1067 Node* const maybe_receiver = a.Parameter(0);
1053 Node* const maybe_string = a->Parameter(1); 1068 Node* const maybe_string = a.Parameter(1);
1054 Node* const context = a->Parameter(4); 1069 Node* const context = a.Parameter(4);
1055 1070
1056 // Ensure {maybe_receiver} is a JSReceiver. 1071 // Ensure {maybe_receiver} is a JSReceiver.
1057 ThrowIfNotJSReceiver(a, isolate, context, maybe_receiver, 1072 ThrowIfNotJSReceiver(&a, isolate, context, maybe_receiver,
1058 MessageTemplate::kIncompatibleMethodReceiver, 1073 MessageTemplate::kIncompatibleMethodReceiver,
1059 "RegExp.prototype.test"); 1074 "RegExp.prototype.test");
1060 Node* const receiver = maybe_receiver; 1075 Node* const receiver = maybe_receiver;
1061 1076
1062 // Convert {maybe_string} to a String. 1077 // Convert {maybe_string} to a String.
1063 Node* const string = a->ToString(context, maybe_string); 1078 Node* const string = a.ToString(context, maybe_string);
1064 1079
1065 // Call exec. 1080 // Call exec.
1066 Node* const match_indices = RegExpExec(a, context, receiver, string); 1081 Node* const match_indices = RegExpExec(&a, context, receiver, string);
1067 1082
1068 // Return true iff exec matched successfully. 1083 // Return true iff exec matched successfully.
1069 Node* const result = a->Select(a->WordEqual(match_indices, a->NullConstant()), 1084 Node* const result = a.Select(a.WordEqual(match_indices, a.NullConstant()),
1070 a->FalseConstant(), a->TrueConstant()); 1085 a.FalseConstant(), a.TrueConstant());
1071 a->Return(result); 1086 a.Return(result);
1072 } 1087 }
1073 1088
1074 // ES#sec-regexp.prototype-@@match 1089 // ES#sec-regexp.prototype-@@match
1075 // RegExp.prototype [ @@match ] ( string ) 1090 // RegExp.prototype [ @@match ] ( string )
1076 BUILTIN(RegExpPrototypeMatch) { 1091 BUILTIN(RegExpPrototypeMatch) {
1077 HandleScope scope(isolate); 1092 HandleScope scope(isolate);
1078 CHECK_RECEIVER(JSReceiver, recv, "RegExp.prototype.@@match"); 1093 CHECK_RECEIVER(JSReceiver, recv, "RegExp.prototype.@@match");
1079 1094
1080 Handle<Object> string_obj = args.atOrUndefined(isolate, 1); 1095 Handle<Object> string_obj = args.atOrUndefined(isolate, 1);
1081 1096
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
1879 } 1894 }
1880 1895
1881 a->Bind(&out); 1896 a->Bind(&out);
1882 return var_result.value(); 1897 return var_result.value();
1883 } 1898 }
1884 1899
1885 } // namespace 1900 } // namespace
1886 1901
1887 // ES#sec-regexp.prototype-@@replace 1902 // ES#sec-regexp.prototype-@@replace
1888 // RegExp.prototype [ @@replace ] ( string, replaceValue ) 1903 // RegExp.prototype [ @@replace ] ( string, replaceValue )
1889 void Builtins::Generate_RegExpPrototypeReplace(CodeStubAssembler* a) { 1904 void Builtins::Generate_RegExpPrototypeReplace(
1905 compiler::CodeAssemblerState* state) {
1890 typedef CodeStubAssembler::Label Label; 1906 typedef CodeStubAssembler::Label Label;
1891 typedef compiler::Node Node; 1907 typedef compiler::Node Node;
1908 CodeStubAssembler a(state);
1892 1909
1893 Isolate* const isolate = a->isolate(); 1910 Isolate* const isolate = a.isolate();
1894 1911
1895 Node* const maybe_receiver = a->Parameter(0); 1912 Node* const maybe_receiver = a.Parameter(0);
1896 Node* const maybe_string = a->Parameter(1); 1913 Node* const maybe_string = a.Parameter(1);
1897 Node* const replace_value = a->Parameter(2); 1914 Node* const replace_value = a.Parameter(2);
1898 Node* const context = a->Parameter(5); 1915 Node* const context = a.Parameter(5);
1899 1916
1900 Node* const int_zero = a->IntPtrConstant(0); 1917 Node* const int_zero = a.IntPtrConstant(0);
1901 1918
1902 // Ensure {maybe_receiver} is a JSReceiver. 1919 // Ensure {maybe_receiver} is a JSReceiver.
1903 Node* const map = 1920 Node* const map =
1904 ThrowIfNotJSReceiver(a, isolate, context, maybe_receiver, 1921 ThrowIfNotJSReceiver(&a, isolate, context, maybe_receiver,
1905 MessageTemplate::kIncompatibleMethodReceiver, 1922 MessageTemplate::kIncompatibleMethodReceiver,
1906 "RegExp.prototype.@@replace"); 1923 "RegExp.prototype.@@replace");
1907 Node* const receiver = maybe_receiver; 1924 Node* const receiver = maybe_receiver;
1908 1925
1909 // Convert {maybe_string} to a String. 1926 // Convert {maybe_string} to a String.
1910 Callable tostring_callable = CodeFactory::ToString(isolate); 1927 Callable tostring_callable = CodeFactory::ToString(isolate);
1911 Node* const string = a->CallStub(tostring_callable, context, maybe_string); 1928 Node* const string = a.CallStub(tostring_callable, context, maybe_string);
1912 1929
1913 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance? 1930 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance?
1914 Label checkreplacecallable(a), runtime(a, Label::kDeferred), fastpath(a); 1931 Label checkreplacecallable(&a), runtime(&a, Label::kDeferred), fastpath(&a);
1915 BranchIfFastPath(a, context, map, &checkreplacecallable, &runtime); 1932 BranchIfFastPath(&a, context, map, &checkreplacecallable, &runtime);
1916 1933
1917 a->Bind(&checkreplacecallable); 1934 a.Bind(&checkreplacecallable);
1918 Node* const regexp = receiver; 1935 Node* const regexp = receiver;
1919 1936
1920 // 2. Is {replace_value} callable? 1937 // 2. Is {replace_value} callable?
1921 Label checkreplacestring(a), if_iscallable(a); 1938 Label checkreplacestring(&a), if_iscallable(&a);
1922 a->GotoIf(a->TaggedIsSmi(replace_value), &checkreplacestring); 1939 a.GotoIf(a.TaggedIsSmi(replace_value), &checkreplacestring);
1923 1940
1924 Node* const replace_value_map = a->LoadMap(replace_value); 1941 Node* const replace_value_map = a.LoadMap(replace_value);
1925 a->Branch(a->IsCallableMap(replace_value_map), &if_iscallable, 1942 a.Branch(a.IsCallableMap(replace_value_map), &if_iscallable,
1926 &checkreplacestring); 1943 &checkreplacestring);
1927 1944
1928 // 3. Does ToString({replace_value}) contain '$'? 1945 // 3. Does ToString({replace_value}) contain '$'?
1929 a->Bind(&checkreplacestring); 1946 a.Bind(&checkreplacestring);
1930 { 1947 {
1931 Node* const replace_string = 1948 Node* const replace_string =
1932 a->CallStub(tostring_callable, context, replace_value); 1949 a.CallStub(tostring_callable, context, replace_value);
1933 1950
1934 Node* const dollar_char = a->IntPtrConstant('$'); 1951 Node* const dollar_char = a.IntPtrConstant('$');
1935 Node* const smi_minusone = a->SmiConstant(Smi::FromInt(-1)); 1952 Node* const smi_minusone = a.SmiConstant(Smi::FromInt(-1));
1936 a->GotoUnless(a->SmiEqual(a->StringIndexOfChar(context, replace_string, 1953 a.GotoUnless(a.SmiEqual(a.StringIndexOfChar(context, replace_string,
1937 dollar_char, int_zero), 1954 dollar_char, int_zero),
1938 smi_minusone), 1955 smi_minusone),
1939 &runtime); 1956 &runtime);
1940 1957
1941 a->Return(ReplaceSimpleStringFastPath(a, context, regexp, string, 1958 a.Return(ReplaceSimpleStringFastPath(&a, context, regexp, string,
1942 replace_string)); 1959 replace_string));
1943 } 1960 }
1944 1961
1945 // {regexp} is unmodified and {replace_value} is callable. 1962 // {regexp} is unmodified and {replace_value} is callable.
1946 a->Bind(&if_iscallable); 1963 a.Bind(&if_iscallable);
1947 { 1964 {
1948 Node* const replace_callable = replace_value; 1965 Node* const replace_callable = replace_value;
1949 1966
1950 // Check if the {regexp} is global. 1967 // Check if the {regexp} is global.
1951 Label if_isglobal(a), if_isnotglobal(a); 1968 Label if_isglobal(&a), if_isnotglobal(&a);
1952 Node* const is_global = FastFlagGetter(a, regexp, JSRegExp::kGlobal); 1969 Node* const is_global = FastFlagGetter(&a, regexp, JSRegExp::kGlobal);
1953 a->Branch(is_global, &if_isglobal, &if_isnotglobal); 1970 a.Branch(is_global, &if_isglobal, &if_isnotglobal);
1954 1971
1955 a->Bind(&if_isglobal); 1972 a.Bind(&if_isglobal);
1956 { 1973 {
1957 Node* const result = ReplaceGlobalCallableFastPath( 1974 Node* const result = ReplaceGlobalCallableFastPath(
1958 a, context, regexp, string, replace_callable); 1975 &a, context, regexp, string, replace_callable);
1959 a->Return(result); 1976 a.Return(result);
1960 } 1977 }
1961 1978
1962 a->Bind(&if_isnotglobal); 1979 a.Bind(&if_isnotglobal);
1963 { 1980 {
1964 Node* const result = 1981 Node* const result =
1965 a->CallRuntime(Runtime::kStringReplaceNonGlobalRegExpWithFunction, 1982 a.CallRuntime(Runtime::kStringReplaceNonGlobalRegExpWithFunction,
1966 context, string, regexp, replace_callable); 1983 context, string, regexp, replace_callable);
1967 a->Return(result); 1984 a.Return(result);
1968 } 1985 }
1969 } 1986 }
1970 1987
1971 a->Bind(&runtime); 1988 a.Bind(&runtime);
1972 { 1989 {
1973 Node* const result = a->CallRuntime(Runtime::kRegExpReplace, context, 1990 Node* const result = a.CallRuntime(Runtime::kRegExpReplace, context,
1974 receiver, string, replace_value); 1991 receiver, string, replace_value);
1975 a->Return(result); 1992 a.Return(result);
1976 } 1993 }
1977 } 1994 }
1978 1995
1979 // Simple string matching functionality for internal use which does not modify 1996 // Simple string matching functionality for internal use which does not modify
1980 // the last match info. 1997 // the last match info.
1981 void Builtins::Generate_RegExpInternalMatch(CodeStubAssembler* a) { 1998 void Builtins::Generate_RegExpInternalMatch(
1999 compiler::CodeAssemblerState* state) {
1982 typedef CodeStubAssembler::Label Label; 2000 typedef CodeStubAssembler::Label Label;
1983 typedef compiler::Node Node; 2001 typedef compiler::Node Node;
2002 CodeStubAssembler a(state);
1984 2003
1985 Isolate* const isolate = a->isolate(); 2004 Isolate* const isolate = a.isolate();
1986 2005
1987 Node* const regexp = a->Parameter(1); 2006 Node* const regexp = a.Parameter(1);
1988 Node* const string = a->Parameter(2); 2007 Node* const string = a.Parameter(2);
1989 Node* const context = a->Parameter(5); 2008 Node* const context = a.Parameter(5);
1990 2009
1991 Node* const null = a->NullConstant(); 2010 Node* const null = a.NullConstant();
1992 Node* const smi_zero = a->SmiConstant(Smi::FromInt(0)); 2011 Node* const smi_zero = a.SmiConstant(Smi::FromInt(0));
1993 2012
1994 Node* const native_context = a->LoadNativeContext(context); 2013 Node* const native_context = a.LoadNativeContext(context);
1995 Node* const internal_match_info = a->LoadContextElement( 2014 Node* const internal_match_info = a.LoadContextElement(
1996 native_context, Context::REGEXP_INTERNAL_MATCH_INFO_INDEX); 2015 native_context, Context::REGEXP_INTERNAL_MATCH_INFO_INDEX);
1997 2016
1998 Callable exec_callable = CodeFactory::RegExpExec(isolate); 2017 Callable exec_callable = CodeFactory::RegExpExec(isolate);
1999 Node* const match_indices = a->CallStub( 2018 Node* const match_indices = a.CallStub(exec_callable, context, regexp, string,
2000 exec_callable, context, regexp, string, smi_zero, internal_match_info); 2019 smi_zero, internal_match_info);
2001 2020
2002 Label if_matched(a), if_didnotmatch(a); 2021 Label if_matched(&a), if_didnotmatch(&a);
2003 a->Branch(a->WordEqual(match_indices, null), &if_didnotmatch, &if_matched); 2022 a.Branch(a.WordEqual(match_indices, null), &if_didnotmatch, &if_matched);
2004 2023
2005 a->Bind(&if_didnotmatch); 2024 a.Bind(&if_didnotmatch);
2006 a->Return(null); 2025 a.Return(null);
2007 2026
2008 a->Bind(&if_matched); 2027 a.Bind(&if_matched);
2009 { 2028 {
2010 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context, 2029 Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context,
2011 match_indices, string); 2030 match_indices, string);
2012 a->Return(result); 2031 a.Return(result);
2013 } 2032 }
2014 } 2033 }
2015 2034
2016 } // namespace internal 2035 } // namespace internal
2017 } // namespace v8 2036 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698