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

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

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