OLD | NEW |
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 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 CASE_FOR_FLAG(JSRegExp::kUnicode, 'u', label_unicode, label_sticky); | 691 CASE_FOR_FLAG(JSRegExp::kUnicode, 'u', label_unicode, label_sticky); |
692 CASE_FOR_FLAG(JSRegExp::kSticky, 'y', label_sticky, out); | 692 CASE_FOR_FLAG(JSRegExp::kSticky, 'y', label_sticky, out); |
693 #undef CASE_FOR_FLAG | 693 #undef CASE_FOR_FLAG |
694 | 694 |
695 a.Bind(&out); | 695 a.Bind(&out); |
696 a.Return(result); | 696 a.Return(result); |
697 } | 697 } |
698 } | 698 } |
699 | 699 |
700 // ES6 21.2.5.10. | 700 // ES6 21.2.5.10. |
701 BUILTIN(RegExpPrototypeSourceGetter) { | 701 void Builtins::Generate_RegExpPrototypeSourceGetter(CodeAssemblerState* state) { |
702 HandleScope scope(isolate); | 702 CodeStubAssembler a(state); |
| 703 Node* const receiver = a.Parameter(0); |
| 704 Node* const context = a.Parameter(3); |
703 | 705 |
704 Handle<Object> recv = args.receiver(); | 706 // Check whether we have an unmodified regexp instance. |
705 if (!recv->IsJSRegExp()) { | 707 CLabel if_isjsregexp(&a), if_isnotjsregexp(&a, CLabel::kDeferred); |
706 Handle<JSFunction> regexp_fun = isolate->regexp_function(); | 708 |
707 if (*recv == regexp_fun->prototype()) { | 709 a.GotoIf(a.TaggedIsSmi(receiver), &if_isnotjsregexp); |
708 isolate->CountUsage(v8::Isolate::kRegExpPrototypeSourceGetter); | 710 a.Branch(a.HasInstanceType(receiver, JS_REGEXP_TYPE), &if_isjsregexp, |
709 return *isolate->factory()->NewStringFromAsciiChecked("(?:)"); | 711 &if_isnotjsregexp); |
710 } | 712 |
711 THROW_NEW_ERROR_RETURN_FAILURE( | 713 a.Bind(&if_isjsregexp); |
712 isolate, NewTypeError(MessageTemplate::kRegExpNonRegExp, | 714 { |
713 isolate->factory()->NewStringFromAsciiChecked( | 715 Node* const source = a.LoadObjectField(receiver, JSRegExp::kSourceOffset); |
714 "RegExp.prototype.source"))); | 716 a.Return(source); |
715 } | 717 } |
716 | 718 |
717 Handle<JSRegExp> regexp = Handle<JSRegExp>::cast(recv); | 719 a.Bind(&if_isnotjsregexp); |
718 return regexp->source(); | 720 { |
| 721 Isolate* isolate = a.isolate(); |
| 722 Node* const native_context = a.LoadNativeContext(context); |
| 723 Node* const regexp_fun = |
| 724 a.LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX); |
| 725 Node* const initial_map = |
| 726 a.LoadObjectField(regexp_fun, JSFunction::kPrototypeOrInitialMapOffset); |
| 727 Node* const initial_prototype = a.LoadMapPrototype(initial_map); |
| 728 |
| 729 CLabel if_isprototype(&a), if_isnotprototype(&a); |
| 730 a.Branch(a.WordEqual(receiver, initial_prototype), &if_isprototype, |
| 731 &if_isnotprototype); |
| 732 |
| 733 a.Bind(&if_isprototype); |
| 734 { |
| 735 const int counter = v8::Isolate::kRegExpPrototypeSourceGetter; |
| 736 Node* const counter_smi = a.SmiConstant(counter); |
| 737 a.CallRuntime(Runtime::kIncrementUseCounter, context, counter_smi); |
| 738 |
| 739 Node* const result = |
| 740 a.HeapConstant(isolate->factory()->NewStringFromAsciiChecked("(?:)")); |
| 741 a.Return(result); |
| 742 } |
| 743 |
| 744 a.Bind(&if_isnotprototype); |
| 745 { |
| 746 Node* const message_id = |
| 747 a.SmiConstant(Smi::FromInt(MessageTemplate::kRegExpNonRegExp)); |
| 748 Node* const method_name_str = |
| 749 a.HeapConstant(isolate->factory()->NewStringFromAsciiChecked( |
| 750 "RegExp.prototype.source")); |
| 751 a.TailCallRuntime(Runtime::kThrowTypeError, context, message_id, |
| 752 method_name_str); |
| 753 } |
| 754 } |
719 } | 755 } |
720 | 756 |
721 BUILTIN(RegExpPrototypeToString) { | 757 BUILTIN(RegExpPrototypeToString) { |
722 HandleScope scope(isolate); | 758 HandleScope scope(isolate); |
723 CHECK_RECEIVER(JSReceiver, recv, "RegExp.prototype.toString"); | 759 CHECK_RECEIVER(JSReceiver, recv, "RegExp.prototype.toString"); |
724 | 760 |
725 if (*recv == isolate->regexp_function()->prototype()) { | 761 if (*recv == isolate->regexp_function()->prototype()) { |
726 isolate->CountUsage(v8::Isolate::kRegExpPrototypeToString); | 762 isolate->CountUsage(v8::Isolate::kRegExpPrototypeToString); |
727 } | 763 } |
728 | 764 |
(...skipping 20 matching lines...) Expand all Loading... |
749 Handle<String> flags_str; | 785 Handle<String> flags_str; |
750 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, flags_str, | 786 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, flags_str, |
751 Object::ToString(isolate, flags)); | 787 Object::ToString(isolate, flags)); |
752 builder.AppendString(flags_str); | 788 builder.AppendString(flags_str); |
753 } | 789 } |
754 | 790 |
755 RETURN_RESULT_OR_FAILURE(isolate, builder.Finish()); | 791 RETURN_RESULT_OR_FAILURE(isolate, builder.Finish()); |
756 } | 792 } |
757 | 793 |
758 // ES6 21.2.4.2. | 794 // ES6 21.2.4.2. |
759 BUILTIN(RegExpPrototypeSpeciesGetter) { | 795 void Builtins::Generate_RegExpPrototypeSpeciesGetter( |
760 HandleScope scope(isolate); | 796 CodeAssemblerState* state) { |
761 return *args.receiver(); | 797 CodeStubAssembler a(state); |
| 798 Node* const receiver = a.Parameter(0); |
| 799 a.Return(receiver); |
762 } | 800 } |
763 | 801 |
764 namespace { | 802 namespace { |
765 | 803 |
766 // Fast-path implementation for flag checks on an unmodified JSRegExp instance. | 804 // Fast-path implementation for flag checks on an unmodified JSRegExp instance. |
767 Node* FastFlagGetter(CodeStubAssembler* a, Node* const regexp, | 805 Node* FastFlagGetter(CodeStubAssembler* a, Node* const regexp, |
768 JSRegExp::Flag flag) { | 806 JSRegExp::Flag flag) { |
769 Node* const smi_zero = a->SmiConstant(Smi::kZero); | 807 Node* const smi_zero = a->SmiConstant(Smi::kZero); |
770 Node* const flags = a->LoadObjectField(regexp, JSRegExp::kFlagsOffset); | 808 Node* const flags = a->LoadObjectField(regexp, JSRegExp::kFlagsOffset); |
771 Node* const mask = a->SmiConstant(Smi::FromInt(flag)); | 809 Node* const mask = a->SmiConstant(Smi::FromInt(flag)); |
(...skipping 1594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2366 a.Bind(&if_matched); | 2404 a.Bind(&if_matched); |
2367 { | 2405 { |
2368 Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context, | 2406 Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context, |
2369 match_indices, string); | 2407 match_indices, string); |
2370 a.Return(result); | 2408 a.Return(result); |
2371 } | 2409 } |
2372 } | 2410 } |
2373 | 2411 |
2374 } // namespace internal | 2412 } // namespace internal |
2375 } // namespace v8 | 2413 } // namespace v8 |
OLD | NEW |