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.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 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 // Check that {receiver} is coercible to Object and convert it to a String. | 706 // Check that {receiver} is coercible to Object and convert it to a String. |
707 receiver = | 707 receiver = |
708 assembler->ToThisString(context, receiver, "String.prototype.charAt"); | 708 assembler->ToThisString(context, receiver, "String.prototype.charAt"); |
709 | 709 |
710 // Convert the {position} to a Smi and check that it's in bounds of the | 710 // Convert the {position} to a Smi and check that it's in bounds of the |
711 // {receiver}. | 711 // {receiver}. |
712 { | 712 { |
713 Label return_emptystring(assembler, Label::kDeferred); | 713 Label return_emptystring(assembler, Label::kDeferred); |
714 position = assembler->ToInteger(context, position, | 714 position = assembler->ToInteger(context, position, |
715 CodeStubAssembler::kTruncateMinusZero); | 715 CodeStubAssembler::kTruncateMinusZero); |
716 assembler->GotoUnless(assembler->WordIsSmi(position), &return_emptystring); | 716 assembler->GotoUnless(assembler->TaggedIsSmi(position), |
| 717 &return_emptystring); |
717 | 718 |
718 // Determine the actual length of the {receiver} String. | 719 // Determine the actual length of the {receiver} String. |
719 Node* receiver_length = | 720 Node* receiver_length = |
720 assembler->LoadObjectField(receiver, String::kLengthOffset); | 721 assembler->LoadObjectField(receiver, String::kLengthOffset); |
721 | 722 |
722 // Return "" if the Smi {position} is outside the bounds of the {receiver}. | 723 // Return "" if the Smi {position} is outside the bounds of the {receiver}. |
723 Label if_positioninbounds(assembler); | 724 Label if_positioninbounds(assembler); |
724 assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length), | 725 assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length), |
725 &return_emptystring, &if_positioninbounds); | 726 &return_emptystring, &if_positioninbounds); |
726 | 727 |
(...skipping 24 matching lines...) Expand all Loading... |
751 // Check that {receiver} is coercible to Object and convert it to a String. | 752 // Check that {receiver} is coercible to Object and convert it to a String. |
752 receiver = | 753 receiver = |
753 assembler->ToThisString(context, receiver, "String.prototype.charCodeAt"); | 754 assembler->ToThisString(context, receiver, "String.prototype.charCodeAt"); |
754 | 755 |
755 // Convert the {position} to a Smi and check that it's in bounds of the | 756 // Convert the {position} to a Smi and check that it's in bounds of the |
756 // {receiver}. | 757 // {receiver}. |
757 { | 758 { |
758 Label return_nan(assembler, Label::kDeferred); | 759 Label return_nan(assembler, Label::kDeferred); |
759 position = assembler->ToInteger(context, position, | 760 position = assembler->ToInteger(context, position, |
760 CodeStubAssembler::kTruncateMinusZero); | 761 CodeStubAssembler::kTruncateMinusZero); |
761 assembler->GotoUnless(assembler->WordIsSmi(position), &return_nan); | 762 assembler->GotoUnless(assembler->TaggedIsSmi(position), &return_nan); |
762 | 763 |
763 // Determine the actual length of the {receiver} String. | 764 // Determine the actual length of the {receiver} String. |
764 Node* receiver_length = | 765 Node* receiver_length = |
765 assembler->LoadObjectField(receiver, String::kLengthOffset); | 766 assembler->LoadObjectField(receiver, String::kLengthOffset); |
766 | 767 |
767 // Return NaN if the Smi {position} is outside the bounds of the {receiver}. | 768 // Return NaN if the Smi {position} is outside the bounds of the {receiver}. |
768 Label if_positioninbounds(assembler); | 769 Label if_positioninbounds(assembler); |
769 assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length), | 770 assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length), |
770 &return_nan, &if_positioninbounds); | 771 &return_nan, &if_positioninbounds); |
771 | 772 |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 a->ToThisString(context, receiver, "String.prototype.substr"); | 993 a->ToThisString(context, receiver, "String.prototype.substr"); |
993 | 994 |
994 Node* const string_length = a->LoadStringLength(string); | 995 Node* const string_length = a->LoadStringLength(string); |
995 | 996 |
996 // Conversions and bounds-checks for {start}. | 997 // Conversions and bounds-checks for {start}. |
997 { | 998 { |
998 Node* const start_int = | 999 Node* const start_int = |
999 a->ToInteger(context, start, CodeStubAssembler::kTruncateMinusZero); | 1000 a->ToInteger(context, start, CodeStubAssembler::kTruncateMinusZero); |
1000 | 1001 |
1001 Label if_issmi(a), if_isheapnumber(a, Label::kDeferred); | 1002 Label if_issmi(a), if_isheapnumber(a, Label::kDeferred); |
1002 a->Branch(a->WordIsSmi(start_int), &if_issmi, &if_isheapnumber); | 1003 a->Branch(a->TaggedIsSmi(start_int), &if_issmi, &if_isheapnumber); |
1003 | 1004 |
1004 a->Bind(&if_issmi); | 1005 a->Bind(&if_issmi); |
1005 { | 1006 { |
1006 Node* const length_plus_start = a->SmiAdd(string_length, start_int); | 1007 Node* const length_plus_start = a->SmiAdd(string_length, start_int); |
1007 var_start.Bind(a->Select(a->SmiLessThan(start_int, zero), | 1008 var_start.Bind(a->Select(a->SmiLessThan(start_int, zero), |
1008 a->SmiMax(length_plus_start, zero), start_int)); | 1009 a->SmiMax(length_plus_start, zero), start_int)); |
1009 a->Goto(&handle_length); | 1010 a->Goto(&handle_length); |
1010 } | 1011 } |
1011 | 1012 |
1012 a->Bind(&if_isheapnumber); | 1013 a->Bind(&if_isheapnumber); |
(...skipping 23 matching lines...) Expand all Loading... |
1036 | 1037 |
1037 a->Bind(&if_isundefined); | 1038 a->Bind(&if_isundefined); |
1038 var_length.Bind(string_length); | 1039 var_length.Bind(string_length); |
1039 a->Goto(&if_issmi); | 1040 a->Goto(&if_issmi); |
1040 | 1041 |
1041 a->Bind(&if_isnotundefined); | 1042 a->Bind(&if_isnotundefined); |
1042 var_length.Bind( | 1043 var_length.Bind( |
1043 a->ToInteger(context, length, CodeStubAssembler::kTruncateMinusZero)); | 1044 a->ToInteger(context, length, CodeStubAssembler::kTruncateMinusZero)); |
1044 } | 1045 } |
1045 | 1046 |
1046 a->Branch(a->WordIsSmi(var_length.value()), &if_issmi, &if_isheapnumber); | 1047 a->Branch(a->TaggedIsSmi(var_length.value()), &if_issmi, &if_isheapnumber); |
1047 | 1048 |
1048 // Set {length} to min(max({length}, 0), {string_length} - {start} | 1049 // Set {length} to min(max({length}, 0), {string_length} - {start} |
1049 a->Bind(&if_issmi); | 1050 a->Bind(&if_issmi); |
1050 { | 1051 { |
1051 Node* const positive_length = a->SmiMax(var_length.value(), zero); | 1052 Node* const positive_length = a->SmiMax(var_length.value(), zero); |
1052 | 1053 |
1053 Node* const minimal_length = a->SmiSub(string_length, var_start.value()); | 1054 Node* const minimal_length = a->SmiSub(string_length, var_start.value()); |
1054 var_length.Bind(a->SmiMin(positive_length, minimal_length)); | 1055 var_length.Bind(a->SmiMin(positive_length, minimal_length)); |
1055 | 1056 |
1056 a->GotoUnless(a->SmiLessThanOrEqual(var_length.value(), zero), &out); | 1057 a->GotoUnless(a->SmiLessThanOrEqual(var_length.value(), zero), &out); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 typedef compiler::Node Node; | 1103 typedef compiler::Node Node; |
1103 typedef CodeStubAssembler::Variable Variable; | 1104 typedef CodeStubAssembler::Variable Variable; |
1104 | 1105 |
1105 Label out(a); | 1106 Label out(a); |
1106 Variable var_result(a, MachineRepresentation::kTagged); | 1107 Variable var_result(a, MachineRepresentation::kTagged); |
1107 | 1108 |
1108 Node* const value_int = | 1109 Node* const value_int = |
1109 a->ToInteger(context, value, CodeStubAssembler::kTruncateMinusZero); | 1110 a->ToInteger(context, value, CodeStubAssembler::kTruncateMinusZero); |
1110 | 1111 |
1111 Label if_issmi(a), if_isnotsmi(a, Label::kDeferred); | 1112 Label if_issmi(a), if_isnotsmi(a, Label::kDeferred); |
1112 a->Branch(a->WordIsSmi(value_int), &if_issmi, &if_isnotsmi); | 1113 a->Branch(a->TaggedIsSmi(value_int), &if_issmi, &if_isnotsmi); |
1113 | 1114 |
1114 a->Bind(&if_issmi); | 1115 a->Bind(&if_issmi); |
1115 { | 1116 { |
1116 Label if_isinbounds(a), if_isoutofbounds(a, Label::kDeferred); | 1117 Label if_isinbounds(a), if_isoutofbounds(a, Label::kDeferred); |
1117 a->Branch(a->SmiAbove(value_int, limit), &if_isoutofbounds, &if_isinbounds); | 1118 a->Branch(a->SmiAbove(value_int, limit), &if_isoutofbounds, &if_isinbounds); |
1118 | 1119 |
1119 a->Bind(&if_isinbounds); | 1120 a->Bind(&if_isinbounds); |
1120 { | 1121 { |
1121 var_result.Bind(value_int); | 1122 var_result.Bind(value_int); |
1122 a->Goto(&out); | 1123 a->Goto(&out); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 | 1423 |
1423 var_value.Bind(assembler->UndefinedConstant()); | 1424 var_value.Bind(assembler->UndefinedConstant()); |
1424 var_done.Bind(assembler->BooleanConstant(true)); | 1425 var_done.Bind(assembler->BooleanConstant(true)); |
1425 | 1426 |
1426 Label throw_bad_receiver(assembler), next_codepoint(assembler), | 1427 Label throw_bad_receiver(assembler), next_codepoint(assembler), |
1427 return_result(assembler); | 1428 return_result(assembler); |
1428 | 1429 |
1429 Node* iterator = assembler->Parameter(0); | 1430 Node* iterator = assembler->Parameter(0); |
1430 Node* context = assembler->Parameter(3); | 1431 Node* context = assembler->Parameter(3); |
1431 | 1432 |
1432 assembler->GotoIf(assembler->WordIsSmi(iterator), &throw_bad_receiver); | 1433 assembler->GotoIf(assembler->TaggedIsSmi(iterator), &throw_bad_receiver); |
1433 assembler->GotoUnless( | 1434 assembler->GotoUnless( |
1434 assembler->WordEqual(assembler->LoadInstanceType(iterator), | 1435 assembler->WordEqual(assembler->LoadInstanceType(iterator), |
1435 assembler->Int32Constant(JS_STRING_ITERATOR_TYPE)), | 1436 assembler->Int32Constant(JS_STRING_ITERATOR_TYPE)), |
1436 &throw_bad_receiver); | 1437 &throw_bad_receiver); |
1437 | 1438 |
1438 Node* string = | 1439 Node* string = |
1439 assembler->LoadObjectField(iterator, JSStringIterator::kStringOffset); | 1440 assembler->LoadObjectField(iterator, JSStringIterator::kStringOffset); |
1440 Node* position = | 1441 Node* position = |
1441 assembler->LoadObjectField(iterator, JSStringIterator::kNextIndexOffset); | 1442 assembler->LoadObjectField(iterator, JSStringIterator::kNextIndexOffset); |
1442 Node* length = assembler->LoadObjectField(string, String::kLengthOffset); | 1443 Node* length = assembler->LoadObjectField(string, String::kLengthOffset); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1484 Runtime::kThrowIncompatibleMethodReceiver, context, | 1485 Runtime::kThrowIncompatibleMethodReceiver, context, |
1485 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( | 1486 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( |
1486 "String Iterator.prototype.next", TENURED)), | 1487 "String Iterator.prototype.next", TENURED)), |
1487 iterator); | 1488 iterator); |
1488 assembler->Return(result); // Never reached. | 1489 assembler->Return(result); // Never reached. |
1489 } | 1490 } |
1490 } | 1491 } |
1491 | 1492 |
1492 } // namespace internal | 1493 } // namespace internal |
1493 } // namespace v8 | 1494 } // namespace v8 |
OLD | NEW |