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

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

Issue 2752213002: [csa] Add CSA::CallBuiltin and Builtins::CallableFor (Closed)
Patch Set: Remove unused variable again 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 2017 the V8 project authors. All rights reserved. 1 // Copyright 2017 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-gen.h" 5 #include "src/builtins/builtins-regexp-gen.h"
6 6
7 #include "src/builtins/builtins-constructor.h" 7 #include "src/builtins/builtins-constructor.h"
8 #include "src/builtins/builtins-utils-gen.h" 8 #include "src/builtins/builtins-utils-gen.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 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 469
470 // ES#sec-regexp.prototype.exec 470 // ES#sec-regexp.prototype.exec
471 // RegExp.prototype.exec ( string ) 471 // RegExp.prototype.exec ( string )
472 // Implements the core of RegExp.prototype.exec but without actually 472 // Implements the core of RegExp.prototype.exec but without actually
473 // constructing the JSRegExpResult. Returns either null (if the RegExp did not 473 // constructing the JSRegExpResult. Returns either null (if the RegExp did not
474 // match) or a fixed array containing match indices as returned by 474 // match) or a fixed array containing match indices as returned by
475 // RegExpExecStub. 475 // RegExpExecStub.
476 Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult( 476 Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
477 Node* const context, Node* const regexp, Node* const string, 477 Node* const context, Node* const regexp, Node* const string,
478 Label* if_didnotmatch, const bool is_fastpath) { 478 Label* if_didnotmatch, const bool is_fastpath) {
479 Isolate* const isolate = this->isolate();
480
481 Node* const null = NullConstant(); 479 Node* const null = NullConstant();
482 Node* const int_zero = IntPtrConstant(0); 480 Node* const int_zero = IntPtrConstant(0);
483 Node* const smi_zero = SmiConstant(Smi::kZero); 481 Node* const smi_zero = SmiConstant(Smi::kZero);
484 482
485 if (!is_fastpath) { 483 if (!is_fastpath) {
486 ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE, 484 ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE,
487 "RegExp.prototype.exec"); 485 "RegExp.prototype.exec");
488 } 486 }
489 487
490 CSA_ASSERT(this, IsStringInstanceType(LoadInstanceType(string))); 488 CSA_ASSERT(this, IsStringInstanceType(LoadInstanceType(string)));
491 CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE)); 489 CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE));
492 490
493 Variable var_result(this, MachineRepresentation::kTagged); 491 Variable var_result(this, MachineRepresentation::kTagged);
494 Label out(this); 492 Label out(this);
495 493
496 // Load lastIndex. 494 // Load lastIndex.
497 Variable var_lastindex(this, MachineRepresentation::kTagged); 495 Variable var_lastindex(this, MachineRepresentation::kTagged);
498 { 496 {
499 Node* const regexp_lastindex = LoadLastIndex(context, regexp, is_fastpath); 497 Node* const regexp_lastindex = LoadLastIndex(context, regexp, is_fastpath);
500 var_lastindex.Bind(regexp_lastindex); 498 var_lastindex.Bind(regexp_lastindex);
501 499
502 // Omit ToLength if lastindex is a non-negative smi. 500 // Omit ToLength if lastindex is a non-negative smi.
503 Label call_tolength(this, Label::kDeferred), next(this); 501 Label call_tolength(this, Label::kDeferred), next(this);
504 Branch(TaggedIsPositiveSmi(regexp_lastindex), &next, &call_tolength); 502 Branch(TaggedIsPositiveSmi(regexp_lastindex), &next, &call_tolength);
505 503
506 Bind(&call_tolength); 504 Bind(&call_tolength);
507 { 505 {
508 Callable tolength_callable = CodeFactory::ToLength(isolate);
509 var_lastindex.Bind( 506 var_lastindex.Bind(
510 CallStub(tolength_callable, context, regexp_lastindex)); 507 CallBuiltin(Builtins::kToLength, context, regexp_lastindex));
511 Goto(&next); 508 Goto(&next);
512 } 509 }
513 510
514 Bind(&next); 511 Bind(&next);
515 } 512 }
516 513
517 // Check whether the regexp is global or sticky, which determines whether we 514 // Check whether the regexp is global or sticky, which determines whether we
518 // update last index later on. 515 // update last index later on.
519 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset); 516 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset);
520 Node* const is_global_or_sticky = WordAnd( 517 Node* const is_global_or_sticky = WordAnd(
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 637
641 Branch(IsJSReceiverInstanceType(value_instance_type), &out, &throw_exception); 638 Branch(IsJSReceiverInstanceType(value_instance_type), &out, &throw_exception);
642 639
643 // The {value} is not a compatible receiver for this method. 640 // The {value} is not a compatible receiver for this method.
644 Bind(&throw_exception); 641 Bind(&throw_exception);
645 { 642 {
646 Node* const message_id = SmiConstant(Smi::FromInt(msg_template)); 643 Node* const message_id = SmiConstant(Smi::FromInt(msg_template));
647 Node* const method_name_str = HeapConstant( 644 Node* const method_name_str = HeapConstant(
648 isolate()->factory()->NewStringFromAsciiChecked(method_name, TENURED)); 645 isolate()->factory()->NewStringFromAsciiChecked(method_name, TENURED));
649 646
650 Callable callable = CodeFactory::ToString(isolate()); 647 Node* const value_str =
651 Node* const value_str = CallStub(callable, context, maybe_receiver); 648 CallBuiltin(Builtins::kToString, context, maybe_receiver);
652 649
653 CallRuntime(Runtime::kThrowTypeError, context, message_id, method_name_str, 650 CallRuntime(Runtime::kThrowTypeError, context, message_id, method_name_str,
654 value_str); 651 value_str);
655 Unreachable(); 652 Unreachable();
656 } 653 }
657 654
658 Bind(&out); 655 Bind(&out);
659 return var_value_map.value(); 656 return var_value_map.value();
660 } 657 }
661 658
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after
1624 Variable var_length_; 1621 Variable var_length_;
1625 Variable var_capacity_; 1622 Variable var_capacity_;
1626 }; 1623 };
1627 1624
1628 } // namespace 1625 } // namespace
1629 1626
1630 void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context, 1627 void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
1631 Node* const regexp, 1628 Node* const regexp,
1632 Node* const string, 1629 Node* const string,
1633 const bool is_fastpath) { 1630 const bool is_fastpath) {
1634 Isolate* const isolate = this->isolate();
1635
1636 Node* const null = NullConstant(); 1631 Node* const null = NullConstant();
1637 Node* const int_zero = IntPtrConstant(0); 1632 Node* const int_zero = IntPtrConstant(0);
1638 Node* const smi_zero = SmiConstant(Smi::kZero); 1633 Node* const smi_zero = SmiConstant(Smi::kZero);
1639 1634
1640 Node* const is_global = 1635 Node* const is_global =
1641 FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath); 1636 FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath);
1642 1637
1643 Label if_isglobal(this), if_isnotglobal(this); 1638 Label if_isglobal(this), if_isnotglobal(this);
1644 Branch(is_global, &if_isglobal, &if_isnotglobal); 1639 Branch(is_global, &if_isglobal, &if_isnotglobal);
1645 1640
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 1733
1739 // Store the match, growing the fixed array if needed. 1734 // Store the match, growing the fixed array if needed.
1740 1735
1741 array.Push(match); 1736 array.Push(match);
1742 1737
1743 // Advance last index if the match is the empty string. 1738 // Advance last index if the match is the empty string.
1744 1739
1745 Node* const match_length = LoadStringLength(match); 1740 Node* const match_length = LoadStringLength(match);
1746 GotoIfNot(SmiEqual(match_length, smi_zero), &loop); 1741 GotoIfNot(SmiEqual(match_length, smi_zero), &loop);
1747 1742
1748 Node* last_index = LoadLastIndex(context, regexp, is_fastpath); 1743 Node* const last_index =
1749 1744 CallBuiltin(Builtins::kToLength, context,
1750 Callable tolength_callable = CodeFactory::ToLength(isolate); 1745 LoadLastIndex(context, regexp, is_fastpath));
1751 last_index = CallStub(tolength_callable, context, last_index);
1752
1753 Node* const new_last_index = 1746 Node* const new_last_index =
1754 AdvanceStringIndex(string, last_index, is_unicode); 1747 AdvanceStringIndex(string, last_index, is_unicode);
1755 1748
1756 StoreLastIndex(context, regexp, new_last_index, is_fastpath); 1749 StoreLastIndex(context, regexp, new_last_index, is_fastpath);
1757 1750
1758 Goto(&loop); 1751 Goto(&loop);
1759 } 1752 }
1760 } 1753 }
1761 1754
1762 Bind(&out); 1755 Bind(&out);
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
2218 "RegExp.prototype.@@split"); 2211 "RegExp.prototype.@@split");
2219 Node* const receiver = maybe_receiver; 2212 Node* const receiver = maybe_receiver;
2220 2213
2221 // Convert {maybe_string} to a String. 2214 // Convert {maybe_string} to a String.
2222 Node* const string = ToString(context, maybe_string); 2215 Node* const string = ToString(context, maybe_string);
2223 2216
2224 Label stub(this), runtime(this, Label::kDeferred); 2217 Label stub(this), runtime(this, Label::kDeferred);
2225 BranchIfFastRegExp(context, map, &stub, &runtime); 2218 BranchIfFastRegExp(context, map, &stub, &runtime);
2226 2219
2227 Bind(&stub); 2220 Bind(&stub);
2228 Callable split_callable = CodeFactory::RegExpSplit(isolate()); 2221 Return(CallBuiltin(Builtins::kRegExpSplit, context, receiver, string,
2229 Return(CallStub(split_callable, context, receiver, string, maybe_limit)); 2222 maybe_limit));
2230 2223
2231 Bind(&runtime); 2224 Bind(&runtime);
2232 Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string, 2225 Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string,
2233 maybe_limit)); 2226 maybe_limit));
2234 } 2227 }
2235 2228
2236 Node* RegExpBuiltinsAssembler::ReplaceGlobalCallableFastPath( 2229 Node* RegExpBuiltinsAssembler::ReplaceGlobalCallableFastPath(
2237 Node* context, Node* regexp, Node* string, Node* replace_callable) { 2230 Node* context, Node* regexp, Node* string, Node* replace_callable) {
2238 // The fast path is reached only if {receiver} is a global unmodified 2231 // The fast path is reached only if {receiver} is a global unmodified
2239 // JSRegExp instance and {replace_callable} is callable. 2232 // JSRegExp instance and {replace_callable} is callable.
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
2557 runtime(this, Label::kDeferred); 2550 runtime(this, Label::kDeferred);
2558 2551
2559 // 2. Is {replace_value} callable? 2552 // 2. Is {replace_value} callable?
2560 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring); 2553 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring);
2561 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable, 2554 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable,
2562 &checkreplacestring); 2555 &checkreplacestring);
2563 2556
2564 // 3. Does ToString({replace_value}) contain '$'? 2557 // 3. Does ToString({replace_value}) contain '$'?
2565 Bind(&checkreplacestring); 2558 Bind(&checkreplacestring);
2566 { 2559 {
2567 Callable tostring_callable = CodeFactory::ToString(isolate());
2568 Node* const replace_string = 2560 Node* const replace_string =
2569 CallStub(tostring_callable, context, replace_value); 2561 CallBuiltin(Builtins::kToString, context, replace_value);
2570 2562
2571 Callable indexof_callable = CodeFactory::StringIndexOf(isolate());
2572 Node* const dollar_string = HeapConstant( 2563 Node* const dollar_string = HeapConstant(
2573 isolate()->factory()->LookupSingleCharacterStringFromCode('$')); 2564 isolate()->factory()->LookupSingleCharacterStringFromCode('$'));
2574 Node* const dollar_ix = CallStub(indexof_callable, context, replace_string, 2565 Node* const dollar_ix =
2575 dollar_string, SmiConstant(0)); 2566 CallBuiltin(Builtins::kStringIndexOf, context, replace_string,
2567 dollar_string, SmiConstant(0));
2576 GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime); 2568 GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime);
2577 2569
2578 Return( 2570 Return(
2579 ReplaceSimpleStringFastPath(context, regexp, string, replace_string)); 2571 ReplaceSimpleStringFastPath(context, regexp, string, replace_string));
2580 } 2572 }
2581 2573
2582 // {regexp} is unmodified and {replace_value} is callable. 2574 // {regexp} is unmodified and {replace_value} is callable.
2583 Bind(&if_iscallable); 2575 Bind(&if_iscallable);
2584 { 2576 {
2585 Node* const replace_fn = replace_value; 2577 Node* const replace_fn = replace_value;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2629 // } 2621 // }
2630 // } 2622 // }
2631 2623
2632 // Ensure {maybe_receiver} is a JSReceiver. 2624 // Ensure {maybe_receiver} is a JSReceiver.
2633 Node* const map = ThrowIfNotJSReceiver( 2625 Node* const map = ThrowIfNotJSReceiver(
2634 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, 2626 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver,
2635 "RegExp.prototype.@@replace"); 2627 "RegExp.prototype.@@replace");
2636 Node* const receiver = maybe_receiver; 2628 Node* const receiver = maybe_receiver;
2637 2629
2638 // Convert {maybe_string} to a String. 2630 // Convert {maybe_string} to a String.
2639 Callable tostring_callable = CodeFactory::ToString(isolate()); 2631 Node* const string = CallBuiltin(Builtins::kToString, context, maybe_string);
2640 Node* const string = CallStub(tostring_callable, context, maybe_string);
2641 2632
2642 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance? 2633 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance?
2643 Label stub(this), runtime(this, Label::kDeferred); 2634 Label stub(this), runtime(this, Label::kDeferred);
2644 BranchIfFastRegExp(context, map, &stub, &runtime); 2635 BranchIfFastRegExp(context, map, &stub, &runtime);
2645 2636
2646 Bind(&stub); 2637 Bind(&stub);
2647 Callable replace_callable = CodeFactory::RegExpReplace(isolate()); 2638 Return(CallBuiltin(Builtins::kRegExpReplace, context, receiver, string,
2648 Return(CallStub(replace_callable, context, receiver, string, replace_value)); 2639 replace_value));
2649 2640
2650 Bind(&runtime); 2641 Bind(&runtime);
2651 Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string, 2642 Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string,
2652 replace_value)); 2643 replace_value));
2653 } 2644 }
2654 2645
2655 // Simple string matching functionality for internal use which does not modify 2646 // Simple string matching functionality for internal use which does not modify
2656 // the last match info. 2647 // the last match info.
2657 TF_BUILTIN(RegExpInternalMatch, RegExpBuiltinsAssembler) { 2648 TF_BUILTIN(RegExpInternalMatch, RegExpBuiltinsAssembler) {
2658 Node* const regexp = Parameter(1); 2649 Node* const regexp = Parameter(1);
(...skipping 19 matching lines...) Expand all
2678 Bind(&if_matched); 2669 Bind(&if_matched);
2679 { 2670 {
2680 Node* result = 2671 Node* result =
2681 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); 2672 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
2682 Return(result); 2673 Return(result);
2683 } 2674 }
2684 } 2675 }
2685 2676
2686 } // namespace internal 2677 } // namespace internal
2687 } // namespace v8 2678 } // namespace v8
OLDNEW
« src/builtins/builtins.cc ('K') | « src/builtins/builtins.cc ('k') | src/callable.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698