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

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

Issue 2752213002: [csa] Add CSA::CallBuiltin and Builtins::CallableFor (Closed)
Patch Set: Remove unused variables Created 3 years, 9 months 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-regexp.h" 5 #include "src/builtins/builtins-regexp.h"
6 6
7 #include "src/builtins/builtins-constructor.h" 7 #include "src/builtins/builtins-constructor.h"
8 #include "src/builtins/builtins-utils.h" 8 #include "src/builtins/builtins-utils.h"
9 #include "src/builtins/builtins.h" 9 #include "src/builtins/builtins.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 474
475 // ES#sec-regexp.prototype.exec 475 // ES#sec-regexp.prototype.exec
476 // RegExp.prototype.exec ( string ) 476 // RegExp.prototype.exec ( string )
477 // Implements the core of RegExp.prototype.exec but without actually 477 // Implements the core of RegExp.prototype.exec but without actually
478 // constructing the JSRegExpResult. Returns either null (if the RegExp did not 478 // constructing the JSRegExpResult. Returns either null (if the RegExp did not
479 // match) or a fixed array containing match indices as returned by 479 // match) or a fixed array containing match indices as returned by
480 // RegExpExecStub. 480 // RegExpExecStub.
481 Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult( 481 Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
482 Node* const context, Node* const regexp, Node* const string, 482 Node* const context, Node* const regexp, Node* const string,
483 Label* if_didnotmatch, const bool is_fastpath) { 483 Label* if_didnotmatch, const bool is_fastpath) {
484 Isolate* const isolate = this->isolate();
485
486 Node* const null = NullConstant(); 484 Node* const null = NullConstant();
487 Node* const int_zero = IntPtrConstant(0); 485 Node* const int_zero = IntPtrConstant(0);
488 Node* const smi_zero = SmiConstant(Smi::kZero); 486 Node* const smi_zero = SmiConstant(Smi::kZero);
489 487
490 if (!is_fastpath) { 488 if (!is_fastpath) {
491 ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE, 489 ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE,
492 "RegExp.prototype.exec"); 490 "RegExp.prototype.exec");
493 } 491 }
494 492
495 CSA_ASSERT(this, IsStringInstanceType(LoadInstanceType(string))); 493 CSA_ASSERT(this, IsStringInstanceType(LoadInstanceType(string)));
496 CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE)); 494 CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE));
497 495
498 Variable var_result(this, MachineRepresentation::kTagged); 496 Variable var_result(this, MachineRepresentation::kTagged);
499 Label out(this); 497 Label out(this);
500 498
501 // Load lastIndex. 499 // Load lastIndex.
502 Variable var_lastindex(this, MachineRepresentation::kTagged); 500 Variable var_lastindex(this, MachineRepresentation::kTagged);
503 { 501 {
504 Node* const regexp_lastindex = LoadLastIndex(context, regexp, is_fastpath); 502 Node* const regexp_lastindex = LoadLastIndex(context, regexp, is_fastpath);
505 var_lastindex.Bind(regexp_lastindex); 503 var_lastindex.Bind(regexp_lastindex);
506 504
507 // Omit ToLength if lastindex is a non-negative smi. 505 // Omit ToLength if lastindex is a non-negative smi.
508 Label call_tolength(this, Label::kDeferred), next(this); 506 Label call_tolength(this, Label::kDeferred), next(this);
509 Branch(TaggedIsPositiveSmi(regexp_lastindex), &next, &call_tolength); 507 Branch(TaggedIsPositiveSmi(regexp_lastindex), &next, &call_tolength);
510 508
511 Bind(&call_tolength); 509 Bind(&call_tolength);
512 { 510 {
513 Callable tolength_callable = CodeFactory::ToLength(isolate);
514 var_lastindex.Bind( 511 var_lastindex.Bind(
515 CallStub(tolength_callable, context, regexp_lastindex)); 512 CallBuiltin(Builtins::kToLength, context, regexp_lastindex));
516 Goto(&next); 513 Goto(&next);
517 } 514 }
518 515
519 Bind(&next); 516 Bind(&next);
520 } 517 }
521 518
522 // Check whether the regexp is global or sticky, which determines whether we 519 // Check whether the regexp is global or sticky, which determines whether we
523 // update last index later on. 520 // update last index later on.
524 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset); 521 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset);
525 Node* const is_global_or_sticky = WordAnd( 522 Node* const is_global_or_sticky = WordAnd(
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 642
646 Branch(IsJSReceiverInstanceType(value_instance_type), &out, &throw_exception); 643 Branch(IsJSReceiverInstanceType(value_instance_type), &out, &throw_exception);
647 644
648 // The {value} is not a compatible receiver for this method. 645 // The {value} is not a compatible receiver for this method.
649 Bind(&throw_exception); 646 Bind(&throw_exception);
650 { 647 {
651 Node* const message_id = SmiConstant(Smi::FromInt(msg_template)); 648 Node* const message_id = SmiConstant(Smi::FromInt(msg_template));
652 Node* const method_name_str = HeapConstant( 649 Node* const method_name_str = HeapConstant(
653 isolate()->factory()->NewStringFromAsciiChecked(method_name, TENURED)); 650 isolate()->factory()->NewStringFromAsciiChecked(method_name, TENURED));
654 651
655 Callable callable = CodeFactory::ToString(isolate()); 652 Node* const value_str =
656 Node* const value_str = CallStub(callable, context, maybe_receiver); 653 CallBuiltin(Builtins::kToString, context, maybe_receiver);
657 654
658 CallRuntime(Runtime::kThrowTypeError, context, message_id, method_name_str, 655 CallRuntime(Runtime::kThrowTypeError, context, message_id, method_name_str,
659 value_str); 656 value_str);
660 Unreachable(); 657 Unreachable();
661 } 658 }
662 659
663 Bind(&out); 660 Bind(&out);
664 return var_value_map.value(); 661 return var_value_map.value();
665 } 662 }
666 663
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after
1748 Variable var_length_; 1745 Variable var_length_;
1749 Variable var_capacity_; 1746 Variable var_capacity_;
1750 }; 1747 };
1751 1748
1752 } // namespace 1749 } // namespace
1753 1750
1754 void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, 1751 void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
1755 Node* const regexp, 1752 Node* const regexp,
1756 Node* const string, 1753 Node* const string,
1757 const bool is_fastpath) { 1754 const bool is_fastpath) {
1758 Isolate* const isolate = this->isolate();
1759
1760 Node* const null = NullConstant(); 1755 Node* const null = NullConstant();
1761 Node* const int_zero = IntPtrConstant(0); 1756 Node* const int_zero = IntPtrConstant(0);
1762 Node* const smi_zero = SmiConstant(Smi::kZero); 1757 Node* const smi_zero = SmiConstant(Smi::kZero);
1763 1758
1764 Node* const is_global = 1759 Node* const is_global =
1765 FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath); 1760 FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath);
1766 1761
1767 Label if_isglobal(this), if_isnotglobal(this); 1762 Label if_isglobal(this), if_isnotglobal(this);
1768 Branch(is_global, &if_isglobal, &if_isnotglobal); 1763 Branch(is_global, &if_isglobal, &if_isnotglobal);
1769 1764
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 // Store the match, growing the fixed array if needed. 1858 // Store the match, growing the fixed array if needed.
1864 1859
1865 array.Push(match); 1860 array.Push(match);
1866 1861
1867 // Advance last index if the match is the empty string. 1862 // Advance last index if the match is the empty string.
1868 1863
1869 Node* const match_length = LoadStringLength(match); 1864 Node* const match_length = LoadStringLength(match);
1870 GotoIfNot(SmiEqual(match_length, smi_zero), &loop); 1865 GotoIfNot(SmiEqual(match_length, smi_zero), &loop);
1871 1866
1872 Node* last_index = LoadLastIndex(context, regexp, is_fastpath); 1867 Node* last_index = LoadLastIndex(context, regexp, is_fastpath);
1873 1868 last_index = CallBuiltin(Builtins::kToLength, context, last_index);
1874 Callable tolength_callable = CodeFactory::ToLength(isolate);
1875 last_index = CallStub(tolength_callable, context, last_index);
1876 1869
1877 Node* const new_last_index = 1870 Node* const new_last_index =
1878 AdvanceStringIndex(string, last_index, is_unicode); 1871 AdvanceStringIndex(string, last_index, is_unicode);
1879 1872
1880 StoreLastIndex(context, regexp, new_last_index, is_fastpath); 1873 StoreLastIndex(context, regexp, new_last_index, is_fastpath);
1881 1874
1882 Goto(&loop); 1875 Goto(&loop);
1883 } 1876 }
1884 } 1877 }
1885 1878
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
2342 "RegExp.prototype.@@split"); 2335 "RegExp.prototype.@@split");
2343 Node* const receiver = maybe_receiver; 2336 Node* const receiver = maybe_receiver;
2344 2337
2345 // Convert {maybe_string} to a String. 2338 // Convert {maybe_string} to a String.
2346 Node* const string = ToString(context, maybe_string); 2339 Node* const string = ToString(context, maybe_string);
2347 2340
2348 Label stub(this), runtime(this, Label::kDeferred); 2341 Label stub(this), runtime(this, Label::kDeferred);
2349 BranchIfFastRegExp(context, map, &stub, &runtime); 2342 BranchIfFastRegExp(context, map, &stub, &runtime);
2350 2343
2351 Bind(&stub); 2344 Bind(&stub);
2352 Callable split_callable = CodeFactory::RegExpSplit(isolate()); 2345 Return(CallBuiltin(Builtins::kRegExpSplit, context, receiver, string,
2353 Return(CallStub(split_callable, context, receiver, string, maybe_limit)); 2346 maybe_limit));
2354 2347
2355 Bind(&runtime); 2348 Bind(&runtime);
2356 Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string, 2349 Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string,
2357 maybe_limit)); 2350 maybe_limit));
2358 } 2351 }
2359 2352
2360 Node* RegExpBuiltinsAssembler::ReplaceGlobalCallableFastPath( 2353 Node* RegExpBuiltinsAssembler::ReplaceGlobalCallableFastPath(
2361 Node* context, Node* regexp, Node* string, Node* replace_callable) { 2354 Node* context, Node* regexp, Node* string, Node* replace_callable) {
2362 // The fast path is reached only if {receiver} is a global unmodified 2355 // The fast path is reached only if {receiver} is a global unmodified
2363 // JSRegExp instance and {replace_callable} is callable. 2356 // JSRegExp instance and {replace_callable} is callable.
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
2679 runtime(this, Label::kDeferred); 2672 runtime(this, Label::kDeferred);
2680 2673
2681 // 2. Is {replace_value} callable? 2674 // 2. Is {replace_value} callable?
2682 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring); 2675 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring);
2683 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable, 2676 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable,
2684 &checkreplacestring); 2677 &checkreplacestring);
2685 2678
2686 // 3. Does ToString({replace_value}) contain '$'? 2679 // 3. Does ToString({replace_value}) contain '$'?
2687 Bind(&checkreplacestring); 2680 Bind(&checkreplacestring);
2688 { 2681 {
2689 Callable tostring_callable = CodeFactory::ToString(isolate());
2690 Node* const replace_string = 2682 Node* const replace_string =
2691 CallStub(tostring_callable, context, replace_value); 2683 CallBuiltin(Builtins::kToString, context, replace_value);
2692 2684
2693 Callable indexof_callable = CodeFactory::StringIndexOf(isolate());
2694 Node* const dollar_string = HeapConstant( 2685 Node* const dollar_string = HeapConstant(
2695 isolate()->factory()->LookupSingleCharacterStringFromCode('$')); 2686 isolate()->factory()->LookupSingleCharacterStringFromCode('$'));
2696 Node* const dollar_ix = CallStub(indexof_callable, context, replace_string, 2687 Node* const dollar_ix =
2697 dollar_string, SmiConstant(0)); 2688 CallBuiltin(Builtins::kStringIndexOf, context, replace_string,
2689 dollar_string, SmiConstant(0));
2698 GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime); 2690 GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime);
2699 2691
2700 Return( 2692 Return(
2701 ReplaceSimpleStringFastPath(context, regexp, string, replace_string)); 2693 ReplaceSimpleStringFastPath(context, regexp, string, replace_string));
2702 } 2694 }
2703 2695
2704 // {regexp} is unmodified and {replace_value} is callable. 2696 // {regexp} is unmodified and {replace_value} is callable.
2705 Bind(&if_iscallable); 2697 Bind(&if_iscallable);
2706 { 2698 {
2707 Node* const replace_fn = replace_value; 2699 Node* const replace_fn = replace_value;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2751 // } 2743 // }
2752 // } 2744 // }
2753 2745
2754 // Ensure {maybe_receiver} is a JSReceiver. 2746 // Ensure {maybe_receiver} is a JSReceiver.
2755 Node* const map = ThrowIfNotJSReceiver( 2747 Node* const map = ThrowIfNotJSReceiver(
2756 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, 2748 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver,
2757 "RegExp.prototype.@@replace"); 2749 "RegExp.prototype.@@replace");
2758 Node* const receiver = maybe_receiver; 2750 Node* const receiver = maybe_receiver;
2759 2751
2760 // Convert {maybe_string} to a String. 2752 // Convert {maybe_string} to a String.
2761 Callable tostring_callable = CodeFactory::ToString(isolate()); 2753 Node* const string = CallBuiltin(Builtins::kToString, context, maybe_string);
2762 Node* const string = CallStub(tostring_callable, context, maybe_string);
2763 2754
2764 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance? 2755 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance?
2765 Label stub(this), runtime(this, Label::kDeferred); 2756 Label stub(this), runtime(this, Label::kDeferred);
2766 BranchIfFastRegExp(context, map, &stub, &runtime); 2757 BranchIfFastRegExp(context, map, &stub, &runtime);
2767 2758
2768 Bind(&stub); 2759 Bind(&stub);
2769 Callable replace_callable = CodeFactory::RegExpReplace(isolate()); 2760 Return(CallBuiltin(Builtins::kRegExpReplace, context, receiver, string,
2770 Return(CallStub(replace_callable, context, receiver, string, replace_value)); 2761 replace_value));
2771 2762
2772 Bind(&runtime); 2763 Bind(&runtime);
2773 Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string, 2764 Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string,
2774 replace_value)); 2765 replace_value));
2775 } 2766 }
2776 2767
2777 // Simple string matching functionality for internal use which does not modify 2768 // Simple string matching functionality for internal use which does not modify
2778 // the last match info. 2769 // the last match info.
2779 TF_BUILTIN(RegExpInternalMatch, RegExpBuiltinsAssembler) { 2770 TF_BUILTIN(RegExpInternalMatch, RegExpBuiltinsAssembler) {
2780 Node* const regexp = Parameter(1); 2771 Node* const regexp = Parameter(1);
(...skipping 19 matching lines...) Expand all
2800 Bind(&if_matched); 2791 Bind(&if_matched);
2801 { 2792 {
2802 Node* result = 2793 Node* result =
2803 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); 2794 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
2804 Return(result); 2795 Return(result);
2805 } 2796 }
2806 } 2797 }
2807 2798
2808 } // namespace internal 2799 } // namespace internal
2809 } // namespace v8 2800 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698