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

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

Issue 2373493002: [stubs] Port String.prototype.substr to TurboFan (Closed)
Patch Set: Created 4 years, 2 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
« no previous file with comments | « src/builtins/builtins.h ('k') | src/js/i18n.js » ('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.h" 5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h" 6 #include "src/builtins/builtins-utils.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 } 574 }
575 575
576 a->Bind(&out); 576 a->Bind(&out);
577 { 577 {
578 Node* result = 578 Node* result =
579 a->SubString(context, string, var_start.value(), var_end.value()); 579 a->SubString(context, string, var_start.value(), var_end.value());
580 a->Return(result); 580 a->Return(result);
581 } 581 }
582 } 582 }
583 583
584 // ES6 section B.2.3.1 String.prototype.substr ( start, length )
585 void Builtins::Generate_StringPrototypeSubstr(CodeStubAssembler* a) {
586 typedef CodeStubAssembler::Label Label;
587 typedef compiler::Node Node;
588 typedef CodeStubAssembler::Variable Variable;
589
590 Label out(a), handle_length(a);
591
592 Variable var_start(a, MachineRepresentation::kTagged);
593 Variable var_length(a, MachineRepresentation::kTagged);
594
595 Node* const receiver = a->Parameter(0);
596 Node* const start = a->Parameter(1);
597 Node* const length = a->Parameter(2);
598 Node* const context = a->Parameter(5);
599
600 // Check that {receiver} is coercible to Object and convert it to a String.
601 Node* const string =
602 a->ToThisString(context, receiver, "String.prototype.substr");
603
604 Node* const string_length = a->LoadStringLength(string);
605
606 // Conversions and bounds-checks for {start}.
607 {
608 Node* const start_int =
609 a->ToInteger(context, start, CodeStubAssembler::kTruncateMinusZero);
610
611 Label if_issmi(a), if_isheapnumber(a, Label::kDeferred);
612 a->Branch(a->WordIsSmi(start_int), &if_issmi, &if_isheapnumber);
613
614 a->Bind(&if_issmi);
615 {
616 Node* const zero = a->SmiConstant(Smi::FromInt(0));
617 Node* const length_plus_start = a->SmiAdd(string_length, start_int);
618 var_start.Bind(a->Select(a->SmiLessThan(start_int, zero),
619 a->SmiMax(length_plus_start, zero), start_int));
620 a->Goto(&handle_length);
621 }
622
623 a->Bind(&if_isheapnumber);
624 {
625 Node* result = a->CallRuntime(Runtime::kThrowIllegalOperation, context);
Igor Sheludko 2016/09/27 12:15:06 String.prototype.substr should not throw. I guess
jgruber 2016/09/29 07:48:49 Thanks, good catch! Modified this to set var_start
626 a->DebugBreak(); // Unreachable.
627 a->Return(result);
628 }
629 }
630
631 // Conversions and bounds-checks for {length}.
632 a->Bind(&handle_length);
633 {
634 // Default to {string_length} if {length} is undefined.
635 {
636 Node* const length_int =
637 a->ToInteger(context, length, CodeStubAssembler::kTruncateMinusZero);
638 var_length.Bind(a->Select(a->WordEqual(length, a->UndefinedConstant()),
639 string_length, length_int));
640 }
641
642 Label if_issmi(a), if_isheapnumber(a, Label::kDeferred);
643 a->Branch(a->WordIsSmi(var_length.value()), &if_issmi, &if_isheapnumber);
644
645 // Set {length} to min(max({length}, 0), {string_length} - {start}
646 a->Bind(&if_issmi);
647 {
648 Node* const zero = a->SmiConstant(Smi::FromInt(0));
649 Node* const positive_length = a->SmiMax(var_length.value(), zero);
650
651 Node* const minimal_length = a->SmiSub(string_length, var_start.value());
652 var_length.Bind(a->SmiMin(positive_length, minimal_length));
653
654 a->GotoUnless(a->SmiLessThanOrEqual(var_length.value(), zero), &out);
655 a->Return(a->EmptyStringConstant());
656 }
657
658 a->Bind(&if_isheapnumber);
659 {
660 // If {length} is a heap number, it is definitely out of bounds. There are
661 // two cases according to the spec: if it is negative, "" is returned; if
662 // it is positive, then length is set to {string_length} - {start}.
663
664 a->Assert(a->WordEqual(a->LoadMap(var_length.value()),
665 a->HeapNumberMapConstant()));
666
667 Label if_isnegative(a), if_ispositive(a);
668 Node* const float_zero = a->Float64Constant(0.);
669 Node* const length_float = a->LoadHeapNumberValue(var_length.value());
670 a->Branch(a->Float64LessThan(length_float, float_zero), &if_isnegative,
671 &if_ispositive);
672
673 a->Bind(&if_isnegative);
674 a->Return(a->EmptyStringConstant());
675
676 a->Bind(&if_ispositive);
677 {
678 var_length.Bind(a->SmiSub(string_length, var_start.value()));
679 a->Goto(&out);
680 }
681 }
682 }
683
684 a->Bind(&out);
685 {
686 Node* const end = a->SmiAdd(var_start.value(), var_length.value());
687 Node* const result = a->SubString(context, string, var_start.value(), end);
688 a->Return(result);
689 }
690 }
691
584 // ES6 section 21.1.3.25 String.prototype.toString () 692 // ES6 section 21.1.3.25 String.prototype.toString ()
585 void Builtins::Generate_StringPrototypeToString(CodeStubAssembler* assembler) { 693 void Builtins::Generate_StringPrototypeToString(CodeStubAssembler* assembler) {
586 typedef compiler::Node Node; 694 typedef compiler::Node Node;
587 695
588 Node* receiver = assembler->Parameter(0); 696 Node* receiver = assembler->Parameter(0);
589 Node* context = assembler->Parameter(3); 697 Node* context = assembler->Parameter(3);
590 698
591 Node* result = assembler->ToThisValue( 699 Node* result = assembler->ToThisValue(
592 context, receiver, PrimitiveType::kString, "String.prototype.toString"); 700 context, receiver, PrimitiveType::kString, "String.prototype.toString");
593 assembler->Return(result); 701 assembler->Return(result);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 } 783 }
676 784
677 iterator->set_string(isolate->heap()->empty_string()); 785 iterator->set_string(isolate->heap()->empty_string());
678 786
679 return *isolate->factory()->NewJSIteratorResult( 787 return *isolate->factory()->NewJSIteratorResult(
680 isolate->factory()->undefined_value(), true); 788 isolate->factory()->undefined_value(), true);
681 } 789 }
682 790
683 } // namespace internal 791 } // namespace internal
684 } // namespace v8 792 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/js/i18n.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698