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 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 Handle<String> valid_forms = | 866 Handle<String> valid_forms = |
867 isolate->factory()->NewStringFromStaticChars("NFC, NFD, NFKC, NFKD"); | 867 isolate->factory()->NewStringFromStaticChars("NFC, NFD, NFKC, NFKD"); |
868 THROW_NEW_ERROR_RETURN_FAILURE( | 868 THROW_NEW_ERROR_RETURN_FAILURE( |
869 isolate, | 869 isolate, |
870 NewRangeError(MessageTemplate::kNormalizationForm, valid_forms)); | 870 NewRangeError(MessageTemplate::kNormalizationForm, valid_forms)); |
871 } | 871 } |
872 | 872 |
873 return *string; | 873 return *string; |
874 } | 874 } |
875 | 875 |
| 876 namespace { |
| 877 |
| 878 compiler::Node* ToSmiBetweenZeroAnd(CodeStubAssembler* a, |
| 879 compiler::Node* context, |
| 880 compiler::Node* value, |
| 881 compiler::Node* limit) { |
| 882 typedef CodeStubAssembler::Label Label; |
| 883 typedef compiler::Node Node; |
| 884 typedef CodeStubAssembler::Variable Variable; |
| 885 |
| 886 Label out(a); |
| 887 Variable var_result(a, MachineRepresentation::kTagged); |
| 888 |
| 889 Node* const value_int = |
| 890 a->ToInteger(context, value, CodeStubAssembler::kTruncateMinusZero); |
| 891 |
| 892 Label if_issmi(a), if_isnotsmi(a, Label::kDeferred); |
| 893 a->Branch(a->WordIsSmi(value_int), &if_issmi, &if_isnotsmi); |
| 894 |
| 895 a->Bind(&if_issmi); |
| 896 { |
| 897 Label if_isinbounds(a), if_isoutofbounds(a, Label::kDeferred); |
| 898 a->Branch(a->SmiAbove(value_int, limit), &if_isoutofbounds, &if_isinbounds); |
| 899 |
| 900 a->Bind(&if_isinbounds); |
| 901 { |
| 902 var_result.Bind(value_int); |
| 903 a->Goto(&out); |
| 904 } |
| 905 |
| 906 a->Bind(&if_isoutofbounds); |
| 907 { |
| 908 Node* const zero = a->SmiConstant(Smi::FromInt(0)); |
| 909 var_result.Bind(a->Select(a->SmiLessThan(value_int, zero), zero, limit)); |
| 910 a->Goto(&out); |
| 911 } |
| 912 } |
| 913 |
| 914 a->Bind(&if_isnotsmi); |
| 915 { |
| 916 // {value} is a heap number - in this case, it is definitely out of bounds. |
| 917 a->Assert(a->WordEqual(a->LoadMap(value_int), a->HeapNumberMapConstant())); |
| 918 |
| 919 Node* const float_zero = a->Float64Constant(0.); |
| 920 Node* const smi_zero = a->SmiConstant(Smi::FromInt(0)); |
| 921 Node* const value_float = a->LoadHeapNumberValue(value_int); |
| 922 var_result.Bind(a->Select(a->Float64LessThan(value_float, float_zero), |
| 923 smi_zero, limit)); |
| 924 a->Goto(&out); |
| 925 } |
| 926 |
| 927 a->Bind(&out); |
| 928 return var_result.value(); |
| 929 } |
| 930 |
| 931 } // namespace |
| 932 |
| 933 // ES6 section 21.1.3.19 String.prototype.substring ( start, end ) |
| 934 void Builtins::Generate_StringPrototypeSubstring(CodeStubAssembler* a) { |
| 935 typedef CodeStubAssembler::Label Label; |
| 936 typedef compiler::Node Node; |
| 937 typedef CodeStubAssembler::Variable Variable; |
| 938 |
| 939 Label out(a); |
| 940 |
| 941 Variable var_start(a, MachineRepresentation::kTagged); |
| 942 Variable var_end(a, MachineRepresentation::kTagged); |
| 943 |
| 944 Node* const receiver = a->Parameter(0); |
| 945 Node* const start = a->Parameter(1); |
| 946 Node* const end = a->Parameter(2); |
| 947 Node* const context = a->Parameter(5); |
| 948 |
| 949 // Check that {receiver} is coercible to Object and convert it to a String. |
| 950 Node* const string = |
| 951 a->ToThisString(context, receiver, "String.prototype.substring"); |
| 952 |
| 953 Node* const length = a->LoadStringLength(string); |
| 954 |
| 955 // Conversion and bounds-checks for {start}. |
| 956 var_start.Bind(ToSmiBetweenZeroAnd(a, context, start, length)); |
| 957 |
| 958 // Conversion and bounds-checks for {end}. |
| 959 { |
| 960 var_end.Bind(length); |
| 961 a->GotoIf(a->WordEqual(end, a->UndefinedConstant()), &out); |
| 962 |
| 963 var_end.Bind(ToSmiBetweenZeroAnd(a, context, end, length)); |
| 964 |
| 965 Label if_endislessthanstart(a); |
| 966 a->Branch(a->SmiLessThan(var_end.value(), var_start.value()), |
| 967 &if_endislessthanstart, &out); |
| 968 |
| 969 a->Bind(&if_endislessthanstart); |
| 970 { |
| 971 Node* const tmp = var_end.value(); |
| 972 var_end.Bind(var_start.value()); |
| 973 var_start.Bind(tmp); |
| 974 a->Goto(&out); |
| 975 } |
| 976 } |
| 977 |
| 978 a->Bind(&out); |
| 979 { |
| 980 Node* result = |
| 981 a->SubString(context, string, var_start.value(), var_end.value()); |
| 982 a->Return(result); |
| 983 } |
| 984 } |
| 985 |
876 // ES6 section 21.1.3.25 String.prototype.toString () | 986 // ES6 section 21.1.3.25 String.prototype.toString () |
877 void Builtins::Generate_StringPrototypeToString(CodeStubAssembler* assembler) { | 987 void Builtins::Generate_StringPrototypeToString(CodeStubAssembler* assembler) { |
878 typedef compiler::Node Node; | 988 typedef compiler::Node Node; |
879 | 989 |
880 Node* receiver = assembler->Parameter(0); | 990 Node* receiver = assembler->Parameter(0); |
881 Node* context = assembler->Parameter(3); | 991 Node* context = assembler->Parameter(3); |
882 | 992 |
883 Node* result = assembler->ToThisValue( | 993 Node* result = assembler->ToThisValue( |
884 context, receiver, PrimitiveType::kString, "String.prototype.toString"); | 994 context, receiver, PrimitiveType::kString, "String.prototype.toString"); |
885 assembler->Return(result); | 995 assembler->Return(result); |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 Runtime::kThrowIncompatibleMethodReceiver, context, | 1462 Runtime::kThrowIncompatibleMethodReceiver, context, |
1353 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( | 1463 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( |
1354 "String Iterator.prototype.next", TENURED)), | 1464 "String Iterator.prototype.next", TENURED)), |
1355 iterator); | 1465 iterator); |
1356 assembler->Return(result); // Never reached. | 1466 assembler->Return(result); // Never reached. |
1357 } | 1467 } |
1358 } | 1468 } |
1359 | 1469 |
1360 } // namespace internal | 1470 } // namespace internal |
1361 } // namespace v8 | 1471 } // namespace v8 |
OLD | NEW |