| 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 |