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

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

Issue 2498073002: [refactoring] Split CodeAssemblerState out of CodeAssembler (Closed)
Patch Set: one more attempt 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
« no previous file with comments | « src/builtins/builtins-object.cc ('k') | src/builtins/builtins-sharedarraybuffer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 } 474 }
475 475
476 a->Bind(&out); 476 a->Bind(&out);
477 return var_result.value(); 477 return var_result.value();
478 } 478 }
479 479
480 } // namespace 480 } // namespace
481 481
482 // ES#sec-regexp.prototype.exec 482 // ES#sec-regexp.prototype.exec
483 // RegExp.prototype.exec ( string ) 483 // RegExp.prototype.exec ( string )
484 void Builtins::Generate_RegExpPrototypeExec(CodeStubAssembler* a) { 484 void Builtins::Generate_RegExpPrototypeExec(
485 compiler::CodeAssemblerState* state) {
485 typedef compiler::Node Node; 486 typedef compiler::Node Node;
487 CodeStubAssembler a(state);
486 488
487 Node* const maybe_receiver = a->Parameter(0); 489 Node* const maybe_receiver = a.Parameter(0);
488 Node* const maybe_string = a->Parameter(1); 490 Node* const maybe_string = a.Parameter(1);
489 Node* const context = a->Parameter(4); 491 Node* const context = a.Parameter(4);
490 492
491 Node* const result = 493 Node* const result =
492 RegExpPrototypeExecInternal(a, context, maybe_receiver, maybe_string); 494 RegExpPrototypeExecInternal(&a, context, maybe_receiver, maybe_string);
493 a->Return(result); 495 a.Return(result);
494 } 496 }
495 497
496 namespace { 498 namespace {
497 499
498 compiler::Node* ThrowIfNotJSReceiver(CodeStubAssembler* a, Isolate* isolate, 500 compiler::Node* ThrowIfNotJSReceiver(CodeStubAssembler* a, Isolate* isolate,
499 compiler::Node* context, 501 compiler::Node* context,
500 compiler::Node* value, 502 compiler::Node* value,
501 MessageTemplate::Template msg_template, 503 MessageTemplate::Template msg_template,
502 char const* method_name) { 504 char const* method_name) {
503 typedef compiler::Node Node; 505 typedef compiler::Node Node;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 a->WordEqual(proto_map, initial_proto_initial_map); 580 a->WordEqual(proto_map, initial_proto_initial_map);
579 581
580 // TODO(ishell): Update this check once map changes for constant field 582 // TODO(ishell): Update this check once map changes for constant field
581 // tracking are landing. 583 // tracking are landing.
582 584
583 a->Branch(proto_has_initialmap, if_isunmodified, if_ismodified); 585 a->Branch(proto_has_initialmap, if_isunmodified, if_ismodified);
584 } 586 }
585 587
586 } // namespace 588 } // namespace
587 589
588 void Builtins::Generate_RegExpPrototypeFlagsGetter(CodeStubAssembler* a) { 590 void Builtins::Generate_RegExpPrototypeFlagsGetter(
591 compiler::CodeAssemblerState* state) {
589 typedef CodeStubAssembler::Variable Variable; 592 typedef CodeStubAssembler::Variable Variable;
590 typedef CodeStubAssembler::Label Label; 593 typedef CodeStubAssembler::Label Label;
591 typedef compiler::Node Node; 594 typedef compiler::Node Node;
595 CodeStubAssembler a(state);
592 596
593 Node* const receiver = a->Parameter(0); 597 Node* const receiver = a.Parameter(0);
594 Node* const context = a->Parameter(3); 598 Node* const context = a.Parameter(3);
595 599
596 Isolate* isolate = a->isolate(); 600 Isolate* isolate = a.isolate();
597 Node* const int_zero = a->IntPtrConstant(0); 601 Node* const int_zero = a.IntPtrConstant(0);
598 Node* const int_one = a->IntPtrConstant(1); 602 Node* const int_one = a.IntPtrConstant(1);
599 603
600 Node* const map = ThrowIfNotJSReceiver(a, isolate, context, receiver, 604 Node* const map = ThrowIfNotJSReceiver(&a, isolate, context, receiver,
601 MessageTemplate::kRegExpNonObject, 605 MessageTemplate::kRegExpNonObject,
602 "RegExp.prototype.flags"); 606 "RegExp.prototype.flags");
603 607
604 Variable var_length(a, MachineType::PointerRepresentation()); 608 Variable var_length(&a, MachineType::PointerRepresentation());
605 Variable var_flags(a, MachineType::PointerRepresentation()); 609 Variable var_flags(&a, MachineType::PointerRepresentation());
606 610
607 // First, count the number of characters we will need and check which flags 611 // First, count the number of characters we will need and check which flags
608 // are set. 612 // are set.
609 613
610 var_length.Bind(int_zero); 614 var_length.Bind(int_zero);
611 615
612 Label if_isunmodifiedjsregexp(a), 616 Label if_isunmodifiedjsregexp(&a),
613 if_isnotunmodifiedjsregexp(a, Label::kDeferred); 617 if_isnotunmodifiedjsregexp(&a, Label::kDeferred);
614 a->Branch(IsInitialRegExpMap(a, context, map), &if_isunmodifiedjsregexp, 618 a.Branch(IsInitialRegExpMap(&a, context, map), &if_isunmodifiedjsregexp,
615 &if_isnotunmodifiedjsregexp); 619 &if_isnotunmodifiedjsregexp);
616 620
617 Label construct_string(a); 621 Label construct_string(&a);
618 a->Bind(&if_isunmodifiedjsregexp); 622 a.Bind(&if_isunmodifiedjsregexp);
619 { 623 {
620 // Refer to JSRegExp's flag property on the fast-path. 624 // Refer to JSRegExp's flag property on the fast-path.
621 Node* const flags_smi = 625 Node* const flags_smi = a.LoadObjectField(receiver, JSRegExp::kFlagsOffset);
622 a->LoadObjectField(receiver, JSRegExp::kFlagsOffset); 626 Node* const flags_intptr = a.SmiUntag(flags_smi);
623 Node* const flags_intptr = a->SmiUntag(flags_smi);
624 var_flags.Bind(flags_intptr); 627 var_flags.Bind(flags_intptr);
625 628
626 Label label_global(a), label_ignorecase(a), label_multiline(a), 629 Label label_global(&a), label_ignorecase(&a), label_multiline(&a),
627 label_unicode(a), label_sticky(a); 630 label_unicode(&a), label_sticky(&a);
628 631
629 #define CASE_FOR_FLAG(FLAG, LABEL, NEXT_LABEL) \ 632 #define CASE_FOR_FLAG(FLAG, LABEL, NEXT_LABEL) \
630 do { \ 633 do { \
631 a->Bind(&LABEL); \ 634 a.Bind(&LABEL); \
632 Node* const mask = a->IntPtrConstant(FLAG); \ 635 Node* const mask = a.IntPtrConstant(FLAG); \
633 a->GotoIf(a->WordEqual(a->WordAnd(flags_intptr, mask), int_zero), \ 636 a.GotoIf(a.WordEqual(a.WordAnd(flags_intptr, mask), int_zero), \
634 &NEXT_LABEL); \ 637 &NEXT_LABEL); \
635 var_length.Bind(a->IntPtrAdd(var_length.value(), int_one)); \ 638 var_length.Bind(a.IntPtrAdd(var_length.value(), int_one)); \
636 a->Goto(&NEXT_LABEL); \ 639 a.Goto(&NEXT_LABEL); \
637 } while (false) 640 } while (false)
638 641
639 a->Goto(&label_global); 642 a.Goto(&label_global);
640 CASE_FOR_FLAG(JSRegExp::kGlobal, label_global, label_ignorecase); 643 CASE_FOR_FLAG(JSRegExp::kGlobal, label_global, label_ignorecase);
641 CASE_FOR_FLAG(JSRegExp::kIgnoreCase, label_ignorecase, label_multiline); 644 CASE_FOR_FLAG(JSRegExp::kIgnoreCase, label_ignorecase, label_multiline);
642 CASE_FOR_FLAG(JSRegExp::kMultiline, label_multiline, label_unicode); 645 CASE_FOR_FLAG(JSRegExp::kMultiline, label_multiline, label_unicode);
643 CASE_FOR_FLAG(JSRegExp::kUnicode, label_unicode, label_sticky); 646 CASE_FOR_FLAG(JSRegExp::kUnicode, label_unicode, label_sticky);
644 CASE_FOR_FLAG(JSRegExp::kSticky, label_sticky, construct_string); 647 CASE_FOR_FLAG(JSRegExp::kSticky, label_sticky, construct_string);
645 #undef CASE_FOR_FLAG 648 #undef CASE_FOR_FLAG
646 } 649 }
647 650
648 a->Bind(&if_isnotunmodifiedjsregexp); 651 a.Bind(&if_isnotunmodifiedjsregexp);
649 { 652 {
650 // Fall back to GetProperty stub on the slow-path. 653 // Fall back to GetProperty stub on the slow-path.
651 var_flags.Bind(int_zero); 654 var_flags.Bind(int_zero);
652 655
653 Callable getproperty_callable = CodeFactory::GetProperty(a->isolate()); 656 Callable getproperty_callable = CodeFactory::GetProperty(a.isolate());
654 Label label_global(a), label_ignorecase(a), label_multiline(a), 657 Label label_global(&a), label_ignorecase(&a), label_multiline(&a),
655 label_unicode(a), label_sticky(a); 658 label_unicode(&a), label_sticky(&a);
656 659
657 #define CASE_FOR_FLAG(NAME, FLAG, LABEL, NEXT_LABEL) \ 660 #define CASE_FOR_FLAG(NAME, FLAG, LABEL, NEXT_LABEL) \
658 do { \ 661 do { \
659 a->Bind(&LABEL); \ 662 a.Bind(&LABEL); \
660 Node* const name = \ 663 Node* const name = \
661 a->HeapConstant(isolate->factory()->NewStringFromAsciiChecked(NAME)); \ 664 a.HeapConstant(isolate->factory()->NewStringFromAsciiChecked(NAME)); \
662 Node* const flag = \ 665 Node* const flag = \
663 a->CallStub(getproperty_callable, context, receiver, name); \ 666 a.CallStub(getproperty_callable, context, receiver, name); \
664 Label if_isflagset(a); \ 667 Label if_isflagset(&a); \
665 a->BranchIfToBooleanIsTrue(flag, &if_isflagset, &NEXT_LABEL); \ 668 a.BranchIfToBooleanIsTrue(flag, &if_isflagset, &NEXT_LABEL); \
666 a->Bind(&if_isflagset); \ 669 a.Bind(&if_isflagset); \
667 var_length.Bind(a->IntPtrAdd(var_length.value(), int_one)); \ 670 var_length.Bind(a.IntPtrAdd(var_length.value(), int_one)); \
668 var_flags.Bind(a->WordOr(var_flags.value(), a->IntPtrConstant(FLAG))); \ 671 var_flags.Bind(a.WordOr(var_flags.value(), a.IntPtrConstant(FLAG))); \
669 a->Goto(&NEXT_LABEL); \ 672 a.Goto(&NEXT_LABEL); \
670 } while (false) 673 } while (false)
671 674
672 a->Goto(&label_global); 675 a.Goto(&label_global);
673 CASE_FOR_FLAG("global", JSRegExp::kGlobal, label_global, label_ignorecase); 676 CASE_FOR_FLAG("global", JSRegExp::kGlobal, label_global, label_ignorecase);
674 CASE_FOR_FLAG("ignoreCase", JSRegExp::kIgnoreCase, label_ignorecase, 677 CASE_FOR_FLAG("ignoreCase", JSRegExp::kIgnoreCase, label_ignorecase,
675 label_multiline); 678 label_multiline);
676 CASE_FOR_FLAG("multiline", JSRegExp::kMultiline, label_multiline, 679 CASE_FOR_FLAG("multiline", JSRegExp::kMultiline, label_multiline,
677 label_unicode); 680 label_unicode);
678 CASE_FOR_FLAG("unicode", JSRegExp::kUnicode, label_unicode, label_sticky); 681 CASE_FOR_FLAG("unicode", JSRegExp::kUnicode, label_unicode, label_sticky);
679 CASE_FOR_FLAG("sticky", JSRegExp::kSticky, label_sticky, construct_string); 682 CASE_FOR_FLAG("sticky", JSRegExp::kSticky, label_sticky, construct_string);
680 #undef CASE_FOR_FLAG 683 #undef CASE_FOR_FLAG
681 } 684 }
682 685
683 // Allocate a string of the required length and fill it with the corresponding 686 // Allocate a string of the required length and fill it with the corresponding
684 // char for each set flag. 687 // char for each set flag.
685 688
686 a->Bind(&construct_string); 689 a.Bind(&construct_string);
687 { 690 {
688 Node* const result = 691 Node* const result =
689 a->AllocateSeqOneByteString(context, var_length.value()); 692 a.AllocateSeqOneByteString(context, var_length.value());
690 Node* const flags_intptr = var_flags.value(); 693 Node* const flags_intptr = var_flags.value();
691 694
692 Variable var_offset(a, MachineType::PointerRepresentation()); 695 Variable var_offset(&a, MachineType::PointerRepresentation());
693 var_offset.Bind( 696 var_offset.Bind(
694 a->IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 697 a.IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag));
695 698
696 Label label_global(a), label_ignorecase(a), label_multiline(a), 699 Label label_global(&a), label_ignorecase(&a), label_multiline(&a),
697 label_unicode(a), label_sticky(a), out(a); 700 label_unicode(&a), label_sticky(&a), out(&a);
698 701
699 #define CASE_FOR_FLAG(FLAG, CHAR, LABEL, NEXT_LABEL) \ 702 #define CASE_FOR_FLAG(FLAG, CHAR, LABEL, NEXT_LABEL) \
700 do { \ 703 do { \
701 a->Bind(&LABEL); \ 704 a.Bind(&LABEL); \
702 Node* const mask = a->IntPtrConstant(FLAG); \ 705 Node* const mask = a.IntPtrConstant(FLAG); \
703 a->GotoIf(a->WordEqual(a->WordAnd(flags_intptr, mask), int_zero), \ 706 a.GotoIf(a.WordEqual(a.WordAnd(flags_intptr, mask), int_zero), \
704 &NEXT_LABEL); \ 707 &NEXT_LABEL); \
705 Node* const value = a->IntPtrConstant(CHAR); \ 708 Node* const value = a.IntPtrConstant(CHAR); \
706 a->StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \ 709 a.StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \
707 var_offset.value(), value); \ 710 var_offset.value(), value); \
708 var_offset.Bind(a->IntPtrAdd(var_offset.value(), int_one)); \ 711 var_offset.Bind(a.IntPtrAdd(var_offset.value(), int_one)); \
709 a->Goto(&NEXT_LABEL); \ 712 a.Goto(&NEXT_LABEL); \
710 } while (false) 713 } while (false)
711 714
712 a->Goto(&label_global); 715 a.Goto(&label_global);
713 CASE_FOR_FLAG(JSRegExp::kGlobal, 'g', label_global, label_ignorecase); 716 CASE_FOR_FLAG(JSRegExp::kGlobal, 'g', label_global, label_ignorecase);
714 CASE_FOR_FLAG(JSRegExp::kIgnoreCase, 'i', label_ignorecase, 717 CASE_FOR_FLAG(JSRegExp::kIgnoreCase, 'i', label_ignorecase,
715 label_multiline); 718 label_multiline);
716 CASE_FOR_FLAG(JSRegExp::kMultiline, 'm', label_multiline, label_unicode); 719 CASE_FOR_FLAG(JSRegExp::kMultiline, 'm', label_multiline, label_unicode);
717 CASE_FOR_FLAG(JSRegExp::kUnicode, 'u', label_unicode, label_sticky); 720 CASE_FOR_FLAG(JSRegExp::kUnicode, 'u', label_unicode, label_sticky);
718 CASE_FOR_FLAG(JSRegExp::kSticky, 'y', label_sticky, out); 721 CASE_FOR_FLAG(JSRegExp::kSticky, 'y', label_sticky, out);
719 #undef CASE_FOR_FLAG 722 #undef CASE_FOR_FLAG
720 723
721 a->Bind(&out); 724 a.Bind(&out);
722 a->Return(result); 725 a.Return(result);
723 } 726 }
724 } 727 }
725 728
726 // ES6 21.2.5.10. 729 // ES6 21.2.5.10.
727 BUILTIN(RegExpPrototypeSourceGetter) { 730 BUILTIN(RegExpPrototypeSourceGetter) {
728 HandleScope scope(isolate); 731 HandleScope scope(isolate);
729 732
730 Handle<Object> recv = args.receiver(); 733 Handle<Object> recv = args.receiver();
731 if (!recv->IsJSRegExp()) { 734 if (!recv->IsJSRegExp()) {
732 Handle<JSFunction> regexp_fun = isolate->regexp_function(); 735 Handle<JSFunction> regexp_fun = isolate->regexp_function();
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 a->CallRuntime(Runtime::kThrowTypeError, context, message_id, 865 a->CallRuntime(Runtime::kThrowTypeError, context, message_id,
863 method_name_str); 866 method_name_str);
864 a->Return(a->UndefinedConstant()); // Never reached. 867 a->Return(a->UndefinedConstant()); // Never reached.
865 } 868 }
866 } 869 }
867 } 870 }
868 871
869 } // namespace 872 } // namespace
870 873
871 // ES6 21.2.5.4. 874 // ES6 21.2.5.4.
872 void Builtins::Generate_RegExpPrototypeGlobalGetter(CodeStubAssembler* a) { 875 void Builtins::Generate_RegExpPrototypeGlobalGetter(
873 Generate_FlagGetter(a, JSRegExp::kGlobal, 876 compiler::CodeAssemblerState* state) {
877 CodeStubAssembler a(state);
878 Generate_FlagGetter(&a, JSRegExp::kGlobal,
874 v8::Isolate::kRegExpPrototypeOldFlagGetter, 879 v8::Isolate::kRegExpPrototypeOldFlagGetter,
875 "RegExp.prototype.global"); 880 "RegExp.prototype.global");
876 } 881 }
877 882
878 // ES6 21.2.5.5. 883 // ES6 21.2.5.5.
879 void Builtins::Generate_RegExpPrototypeIgnoreCaseGetter(CodeStubAssembler* a) { 884 void Builtins::Generate_RegExpPrototypeIgnoreCaseGetter(
880 Generate_FlagGetter(a, JSRegExp::kIgnoreCase, 885 compiler::CodeAssemblerState* state) {
886 CodeStubAssembler a(state);
887 Generate_FlagGetter(&a, JSRegExp::kIgnoreCase,
881 v8::Isolate::kRegExpPrototypeOldFlagGetter, 888 v8::Isolate::kRegExpPrototypeOldFlagGetter,
882 "RegExp.prototype.ignoreCase"); 889 "RegExp.prototype.ignoreCase");
883 } 890 }
884 891
885 // ES6 21.2.5.7. 892 // ES6 21.2.5.7.
886 void Builtins::Generate_RegExpPrototypeMultilineGetter(CodeStubAssembler* a) { 893 void Builtins::Generate_RegExpPrototypeMultilineGetter(
887 Generate_FlagGetter(a, JSRegExp::kMultiline, 894 compiler::CodeAssemblerState* state) {
895 CodeStubAssembler a(state);
896 Generate_FlagGetter(&a, JSRegExp::kMultiline,
888 v8::Isolate::kRegExpPrototypeOldFlagGetter, 897 v8::Isolate::kRegExpPrototypeOldFlagGetter,
889 "RegExp.prototype.multiline"); 898 "RegExp.prototype.multiline");
890 } 899 }
891 900
892 // ES6 21.2.5.12. 901 // ES6 21.2.5.12.
893 void Builtins::Generate_RegExpPrototypeStickyGetter(CodeStubAssembler* a) { 902 void Builtins::Generate_RegExpPrototypeStickyGetter(
894 Generate_FlagGetter(a, JSRegExp::kSticky, 903 compiler::CodeAssemblerState* state) {
904 CodeStubAssembler a(state);
905 Generate_FlagGetter(&a, JSRegExp::kSticky,
895 v8::Isolate::kRegExpPrototypeStickyGetter, 906 v8::Isolate::kRegExpPrototypeStickyGetter,
896 "RegExp.prototype.sticky"); 907 "RegExp.prototype.sticky");
897 } 908 }
898 909
899 // ES6 21.2.5.15. 910 // ES6 21.2.5.15.
900 void Builtins::Generate_RegExpPrototypeUnicodeGetter(CodeStubAssembler* a) { 911 void Builtins::Generate_RegExpPrototypeUnicodeGetter(
901 Generate_FlagGetter(a, JSRegExp::kUnicode, 912 compiler::CodeAssemblerState* state) {
913 CodeStubAssembler a(state);
914 Generate_FlagGetter(&a, JSRegExp::kUnicode,
902 v8::Isolate::kRegExpPrototypeUnicodeGetter, 915 v8::Isolate::kRegExpPrototypeUnicodeGetter,
903 "RegExp.prototype.unicode"); 916 "RegExp.prototype.unicode");
904 } 917 }
905 918
906 // The properties $1..$9 are the first nine capturing substrings of the last 919 // The properties $1..$9 are the first nine capturing substrings of the last
907 // successful match, or ''. The function RegExpMakeCaptureGetter will be 920 // successful match, or ''. The function RegExpMakeCaptureGetter will be
908 // called with indices from 1 to 9. 921 // called with indices from 1 to 9.
909 #define DEFINE_CAPTURE_GETTER(i) \ 922 #define DEFINE_CAPTURE_GETTER(i) \
910 BUILTIN(RegExpCapture##i##Getter) { \ 923 BUILTIN(RegExpCapture##i##Getter) { \
911 HandleScope scope(isolate); \ 924 HandleScope scope(isolate); \
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 } 1067 }
1055 1068
1056 a->Bind(&out); 1069 a->Bind(&out);
1057 return var_result.value(); 1070 return var_result.value();
1058 } 1071 }
1059 1072
1060 } // namespace 1073 } // namespace
1061 1074
1062 // ES#sec-regexp.prototype.test 1075 // ES#sec-regexp.prototype.test
1063 // RegExp.prototype.test ( S ) 1076 // RegExp.prototype.test ( S )
1064 void Builtins::Generate_RegExpPrototypeTest(CodeStubAssembler* a) { 1077 void Builtins::Generate_RegExpPrototypeTest(
1078 compiler::CodeAssemblerState* state) {
1065 typedef compiler::Node Node; 1079 typedef compiler::Node Node;
1080 CodeStubAssembler a(state);
1066 1081
1067 Isolate* const isolate = a->isolate(); 1082 Isolate* const isolate = a.isolate();
1068 1083
1069 Node* const maybe_receiver = a->Parameter(0); 1084 Node* const maybe_receiver = a.Parameter(0);
1070 Node* const maybe_string = a->Parameter(1); 1085 Node* const maybe_string = a.Parameter(1);
1071 Node* const context = a->Parameter(4); 1086 Node* const context = a.Parameter(4);
1072 1087
1073 // Ensure {maybe_receiver} is a JSReceiver. 1088 // Ensure {maybe_receiver} is a JSReceiver.
1074 ThrowIfNotJSReceiver(a, isolate, context, maybe_receiver, 1089 ThrowIfNotJSReceiver(&a, isolate, context, maybe_receiver,
1075 MessageTemplate::kIncompatibleMethodReceiver, 1090 MessageTemplate::kIncompatibleMethodReceiver,
1076 "RegExp.prototype.test"); 1091 "RegExp.prototype.test");
1077 Node* const receiver = maybe_receiver; 1092 Node* const receiver = maybe_receiver;
1078 1093
1079 // Convert {maybe_string} to a String. 1094 // Convert {maybe_string} to a String.
1080 Node* const string = a->ToString(context, maybe_string); 1095 Node* const string = a.ToString(context, maybe_string);
1081 1096
1082 // Call exec. 1097 // Call exec.
1083 Node* const match_indices = RegExpExec(a, context, receiver, string); 1098 Node* const match_indices = RegExpExec(&a, context, receiver, string);
1084 1099
1085 // Return true iff exec matched successfully. 1100 // Return true iff exec matched successfully.
1086 Node* const result = a->Select(a->WordEqual(match_indices, a->NullConstant()), 1101 Node* const result = a.Select(a.WordEqual(match_indices, a.NullConstant()),
1087 a->FalseConstant(), a->TrueConstant()); 1102 a.FalseConstant(), a.TrueConstant());
1088 a->Return(result); 1103 a.Return(result);
1089 } 1104 }
1090 1105
1091 // ES#sec-regexp.prototype-@@match 1106 // ES#sec-regexp.prototype-@@match
1092 // RegExp.prototype [ @@match ] ( string ) 1107 // RegExp.prototype [ @@match ] ( string )
1093 BUILTIN(RegExpPrototypeMatch) { 1108 BUILTIN(RegExpPrototypeMatch) {
1094 HandleScope scope(isolate); 1109 HandleScope scope(isolate);
1095 CHECK_RECEIVER(JSReceiver, recv, "RegExp.prototype.@@match"); 1110 CHECK_RECEIVER(JSReceiver, recv, "RegExp.prototype.@@match");
1096 1111
1097 Handle<Object> string_obj = args.atOrUndefined(isolate, 1); 1112 Handle<Object> string_obj = args.atOrUndefined(isolate, 1);
1098 1113
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 a->CallStub(getproperty_callable, context, match_indices, name); 1261 a->CallStub(getproperty_callable, context, match_indices, name);
1247 a->Return(index); 1262 a->Return(index);
1248 } 1263 }
1249 } 1264 }
1250 } 1265 }
1251 1266
1252 } // namespace 1267 } // namespace
1253 1268
1254 // ES#sec-regexp.prototype-@@search 1269 // ES#sec-regexp.prototype-@@search
1255 // RegExp.prototype [ @@search ] ( string ) 1270 // RegExp.prototype [ @@search ] ( string )
1256 void Builtins::Generate_RegExpPrototypeSearch(CodeStubAssembler* a) { 1271 void Builtins::Generate_RegExpPrototypeSearch(
1272 compiler::CodeAssemblerState* state) {
1257 typedef CodeStubAssembler::Label Label; 1273 typedef CodeStubAssembler::Label Label;
1258 typedef compiler::Node Node; 1274 typedef compiler::Node Node;
1275 CodeStubAssembler a(state);
1259 1276
1260 Isolate* const isolate = a->isolate(); 1277 Isolate* const isolate = a.isolate();
1261 1278
1262 Node* const maybe_receiver = a->Parameter(0); 1279 Node* const maybe_receiver = a.Parameter(0);
1263 Node* const maybe_string = a->Parameter(1); 1280 Node* const maybe_string = a.Parameter(1);
1264 Node* const context = a->Parameter(4); 1281 Node* const context = a.Parameter(4);
1265 1282
1266 // Ensure {maybe_receiver} is a JSReceiver. 1283 // Ensure {maybe_receiver} is a JSReceiver.
1267 Node* const map = 1284 Node* const map =
1268 ThrowIfNotJSReceiver(a, isolate, context, maybe_receiver, 1285 ThrowIfNotJSReceiver(&a, isolate, context, maybe_receiver,
1269 MessageTemplate::kIncompatibleMethodReceiver, 1286 MessageTemplate::kIncompatibleMethodReceiver,
1270 "RegExp.prototype.@@search"); 1287 "RegExp.prototype.@@search");
1271 Node* const receiver = maybe_receiver; 1288 Node* const receiver = maybe_receiver;
1272 1289
1273 // Convert {maybe_string} to a String. 1290 // Convert {maybe_string} to a String.
1274 Node* const string = a->ToString(context, maybe_string); 1291 Node* const string = a.ToString(context, maybe_string);
1275 1292
1276 Label fast_path(a), slow_path(a); 1293 Label fast_path(&a), slow_path(&a);
1277 BranchIfFastPath(a, context, map, &fast_path, &slow_path); 1294 BranchIfFastPath(&a, context, map, &fast_path, &slow_path);
1278 1295
1279 a->Bind(&fast_path); 1296 a.Bind(&fast_path);
1280 Generate_RegExpPrototypeSearchBody(a, receiver, string, context, true); 1297 Generate_RegExpPrototypeSearchBody(&a, receiver, string, context, true);
1281 1298
1282 a->Bind(&slow_path); 1299 a.Bind(&slow_path);
1283 Generate_RegExpPrototypeSearchBody(a, receiver, string, context, false); 1300 Generate_RegExpPrototypeSearchBody(&a, receiver, string, context, false);
1284 } 1301 }
1285 1302
1286 namespace { 1303 namespace {
1287 1304
1288 MUST_USE_RESULT MaybeHandle<Object> ToUint32(Isolate* isolate, 1305 MUST_USE_RESULT MaybeHandle<Object> ToUint32(Isolate* isolate,
1289 Handle<Object> object, 1306 Handle<Object> object,
1290 uint32_t* out) { 1307 uint32_t* out) {
1291 if (object->IsUndefined(isolate)) { 1308 if (object->IsUndefined(isolate)) {
1292 *out = kMaxUInt32; 1309 *out = kMaxUInt32;
1293 return object; 1310 return object;
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
1967 } 1984 }
1968 1985
1969 a->Bind(&out); 1986 a->Bind(&out);
1970 return var_result.value(); 1987 return var_result.value();
1971 } 1988 }
1972 1989
1973 } // namespace 1990 } // namespace
1974 1991
1975 // ES#sec-regexp.prototype-@@replace 1992 // ES#sec-regexp.prototype-@@replace
1976 // RegExp.prototype [ @@replace ] ( string, replaceValue ) 1993 // RegExp.prototype [ @@replace ] ( string, replaceValue )
1977 void Builtins::Generate_RegExpPrototypeReplace(CodeStubAssembler* a) { 1994 void Builtins::Generate_RegExpPrototypeReplace(
1995 compiler::CodeAssemblerState* state) {
1978 typedef CodeStubAssembler::Label Label; 1996 typedef CodeStubAssembler::Label Label;
1979 typedef compiler::Node Node; 1997 typedef compiler::Node Node;
1998 CodeStubAssembler a(state);
1980 1999
1981 Isolate* const isolate = a->isolate(); 2000 Isolate* const isolate = a.isolate();
1982 2001
1983 Node* const maybe_receiver = a->Parameter(0); 2002 Node* const maybe_receiver = a.Parameter(0);
1984 Node* const maybe_string = a->Parameter(1); 2003 Node* const maybe_string = a.Parameter(1);
1985 Node* const replace_value = a->Parameter(2); 2004 Node* const replace_value = a.Parameter(2);
1986 Node* const context = a->Parameter(5); 2005 Node* const context = a.Parameter(5);
1987 2006
1988 Node* const int_zero = a->IntPtrConstant(0); 2007 Node* const int_zero = a.IntPtrConstant(0);
1989 2008
1990 // Ensure {maybe_receiver} is a JSReceiver. 2009 // Ensure {maybe_receiver} is a JSReceiver.
1991 Node* const map = 2010 Node* const map =
1992 ThrowIfNotJSReceiver(a, isolate, context, maybe_receiver, 2011 ThrowIfNotJSReceiver(&a, isolate, context, maybe_receiver,
1993 MessageTemplate::kIncompatibleMethodReceiver, 2012 MessageTemplate::kIncompatibleMethodReceiver,
1994 "RegExp.prototype.@@replace"); 2013 "RegExp.prototype.@@replace");
1995 Node* const receiver = maybe_receiver; 2014 Node* const receiver = maybe_receiver;
1996 2015
1997 // Convert {maybe_string} to a String. 2016 // Convert {maybe_string} to a String.
1998 Callable tostring_callable = CodeFactory::ToString(isolate); 2017 Callable tostring_callable = CodeFactory::ToString(isolate);
1999 Node* const string = a->CallStub(tostring_callable, context, maybe_string); 2018 Node* const string = a.CallStub(tostring_callable, context, maybe_string);
2000 2019
2001 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance? 2020 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance?
2002 Label checkreplacecallable(a), runtime(a, Label::kDeferred), fastpath(a); 2021 Label checkreplacecallable(&a), runtime(&a, Label::kDeferred), fastpath(&a);
2003 BranchIfFastPath(a, context, map, &checkreplacecallable, &runtime); 2022 BranchIfFastPath(&a, context, map, &checkreplacecallable, &runtime);
2004 2023
2005 a->Bind(&checkreplacecallable); 2024 a.Bind(&checkreplacecallable);
2006 Node* const regexp = receiver; 2025 Node* const regexp = receiver;
2007 2026
2008 // 2. Is {replace_value} callable? 2027 // 2. Is {replace_value} callable?
2009 Label checkreplacestring(a), if_iscallable(a); 2028 Label checkreplacestring(&a), if_iscallable(&a);
2010 a->GotoIf(a->TaggedIsSmi(replace_value), &checkreplacestring); 2029 a.GotoIf(a.TaggedIsSmi(replace_value), &checkreplacestring);
2011 2030
2012 Node* const replace_value_map = a->LoadMap(replace_value); 2031 Node* const replace_value_map = a.LoadMap(replace_value);
2013 a->Branch(a->IsCallableMap(replace_value_map), &if_iscallable, 2032 a.Branch(a.IsCallableMap(replace_value_map), &if_iscallable,
2014 &checkreplacestring); 2033 &checkreplacestring);
2015 2034
2016 // 3. Does ToString({replace_value}) contain '$'? 2035 // 3. Does ToString({replace_value}) contain '$'?
2017 a->Bind(&checkreplacestring); 2036 a.Bind(&checkreplacestring);
2018 { 2037 {
2019 Node* const replace_string = 2038 Node* const replace_string =
2020 a->CallStub(tostring_callable, context, replace_value); 2039 a.CallStub(tostring_callable, context, replace_value);
2021 2040
2022 Node* const dollar_char = a->IntPtrConstant('$'); 2041 Node* const dollar_char = a.IntPtrConstant('$');
2023 Node* const smi_minusone = a->SmiConstant(Smi::FromInt(-1)); 2042 Node* const smi_minusone = a.SmiConstant(Smi::FromInt(-1));
2024 a->GotoUnless(a->SmiEqual(a->StringIndexOfChar(context, replace_string, 2043 a.GotoUnless(a.SmiEqual(a.StringIndexOfChar(context, replace_string,
2025 dollar_char, int_zero), 2044 dollar_char, int_zero),
2026 smi_minusone), 2045 smi_minusone),
2027 &runtime); 2046 &runtime);
2028 2047
2029 a->Return(ReplaceSimpleStringFastPath(a, context, regexp, string, 2048 a.Return(ReplaceSimpleStringFastPath(&a, context, regexp, string,
2030 replace_string)); 2049 replace_string));
2031 } 2050 }
2032 2051
2033 // {regexp} is unmodified and {replace_value} is callable. 2052 // {regexp} is unmodified and {replace_value} is callable.
2034 a->Bind(&if_iscallable); 2053 a.Bind(&if_iscallable);
2035 { 2054 {
2036 Node* const replace_callable = replace_value; 2055 Node* const replace_callable = replace_value;
2037 2056
2038 // Check if the {regexp} is global. 2057 // Check if the {regexp} is global.
2039 Label if_isglobal(a), if_isnotglobal(a); 2058 Label if_isglobal(&a), if_isnotglobal(&a);
2040 Node* const is_global = FastFlagGetter(a, regexp, JSRegExp::kGlobal); 2059 Node* const is_global = FastFlagGetter(&a, regexp, JSRegExp::kGlobal);
2041 a->Branch(is_global, &if_isglobal, &if_isnotglobal); 2060 a.Branch(is_global, &if_isglobal, &if_isnotglobal);
2042 2061
2043 a->Bind(&if_isglobal); 2062 a.Bind(&if_isglobal);
2044 { 2063 {
2045 Node* const result = ReplaceGlobalCallableFastPath( 2064 Node* const result = ReplaceGlobalCallableFastPath(
2046 a, context, regexp, string, replace_callable); 2065 &a, context, regexp, string, replace_callable);
2047 a->Return(result); 2066 a.Return(result);
2048 } 2067 }
2049 2068
2050 a->Bind(&if_isnotglobal); 2069 a.Bind(&if_isnotglobal);
2051 { 2070 {
2052 Node* const result = 2071 Node* const result =
2053 a->CallRuntime(Runtime::kStringReplaceNonGlobalRegExpWithFunction, 2072 a.CallRuntime(Runtime::kStringReplaceNonGlobalRegExpWithFunction,
2054 context, string, regexp, replace_callable); 2073 context, string, regexp, replace_callable);
2055 a->Return(result); 2074 a.Return(result);
2056 } 2075 }
2057 } 2076 }
2058 2077
2059 a->Bind(&runtime); 2078 a.Bind(&runtime);
2060 { 2079 {
2061 Node* const result = a->CallRuntime(Runtime::kRegExpReplace, context, 2080 Node* const result = a.CallRuntime(Runtime::kRegExpReplace, context,
2062 receiver, string, replace_value); 2081 receiver, string, replace_value);
2063 a->Return(result); 2082 a.Return(result);
2064 } 2083 }
2065 } 2084 }
2066 2085
2067 // Simple string matching functionality for internal use which does not modify 2086 // Simple string matching functionality for internal use which does not modify
2068 // the last match info. 2087 // the last match info.
2069 void Builtins::Generate_RegExpInternalMatch(CodeStubAssembler* a) { 2088 void Builtins::Generate_RegExpInternalMatch(
2089 compiler::CodeAssemblerState* state) {
2070 typedef CodeStubAssembler::Label Label; 2090 typedef CodeStubAssembler::Label Label;
2071 typedef compiler::Node Node; 2091 typedef compiler::Node Node;
2092 CodeStubAssembler a(state);
2072 2093
2073 Isolate* const isolate = a->isolate(); 2094 Isolate* const isolate = a.isolate();
2074 2095
2075 Node* const regexp = a->Parameter(1); 2096 Node* const regexp = a.Parameter(1);
2076 Node* const string = a->Parameter(2); 2097 Node* const string = a.Parameter(2);
2077 Node* const context = a->Parameter(5); 2098 Node* const context = a.Parameter(5);
2078 2099
2079 Node* const null = a->NullConstant(); 2100 Node* const null = a.NullConstant();
2080 Node* const smi_zero = a->SmiConstant(Smi::FromInt(0)); 2101 Node* const smi_zero = a.SmiConstant(Smi::FromInt(0));
2081 2102
2082 Node* const native_context = a->LoadNativeContext(context); 2103 Node* const native_context = a.LoadNativeContext(context);
2083 Node* const internal_match_info = a->LoadContextElement( 2104 Node* const internal_match_info = a.LoadContextElement(
2084 native_context, Context::REGEXP_INTERNAL_MATCH_INFO_INDEX); 2105 native_context, Context::REGEXP_INTERNAL_MATCH_INFO_INDEX);
2085 2106
2086 Callable exec_callable = CodeFactory::RegExpExec(isolate); 2107 Callable exec_callable = CodeFactory::RegExpExec(isolate);
2087 Node* const match_indices = a->CallStub( 2108 Node* const match_indices = a.CallStub(exec_callable, context, regexp, string,
2088 exec_callable, context, regexp, string, smi_zero, internal_match_info); 2109 smi_zero, internal_match_info);
2089 2110
2090 Label if_matched(a), if_didnotmatch(a); 2111 Label if_matched(&a), if_didnotmatch(&a);
2091 a->Branch(a->WordEqual(match_indices, null), &if_didnotmatch, &if_matched); 2112 a.Branch(a.WordEqual(match_indices, null), &if_didnotmatch, &if_matched);
2092 2113
2093 a->Bind(&if_didnotmatch); 2114 a.Bind(&if_didnotmatch);
2094 a->Return(null); 2115 a.Return(null);
2095 2116
2096 a->Bind(&if_matched); 2117 a.Bind(&if_matched);
2097 { 2118 {
2098 Node* result = ConstructNewResultFromMatchInfo(isolate, a, context, 2119 Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context,
2099 match_indices, string); 2120 match_indices, string);
2100 a->Return(result); 2121 a.Return(result);
2101 } 2122 }
2102 } 2123 }
2103 2124
2104 } // namespace internal 2125 } // namespace internal
2105 } // namespace v8 2126 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-object.cc ('k') | src/builtins/builtins-sharedarraybuffer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698