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-utils.h" | 5 #include "src/builtins/builtins-utils.h" |
6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
| 7 #include "src/code-factory.h" |
7 #include "src/code-stub-assembler.h" | 8 #include "src/code-stub-assembler.h" |
8 #include "src/dateparser-inl.h" | 9 #include "src/dateparser-inl.h" |
9 | 10 |
10 namespace v8 { | 11 namespace v8 { |
11 namespace internal { | 12 namespace internal { |
12 | 13 |
13 // ----------------------------------------------------------------------------- | 14 // ----------------------------------------------------------------------------- |
14 // ES6 section 20.3 Date Objects | 15 // ES6 section 20.3 Date Objects |
15 | 16 |
16 namespace { | 17 namespace { |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 int64_t time_ms = static_cast<int64_t>(time_val); | 818 int64_t time_ms = static_cast<int64_t>(time_val); |
818 int year, month, day, weekday, hour, min, sec, ms; | 819 int year, month, day, weekday, hour, min, sec, ms; |
819 isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday, | 820 isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday, |
820 &hour, &min, &sec, &ms); | 821 &hour, &min, &sec, &ms); |
821 SNPrintF(ArrayVector(buffer), "%s, %02d %s %4d %02d:%02d:%02d GMT", | 822 SNPrintF(ArrayVector(buffer), "%s, %02d %s %4d %02d:%02d:%02d GMT", |
822 kShortWeekDays[weekday], day, kShortMonths[month], year, hour, min, | 823 kShortWeekDays[weekday], day, kShortMonths[month], year, hour, min, |
823 sec); | 824 sec); |
824 return *isolate->factory()->NewStringFromAsciiChecked(buffer); | 825 return *isolate->factory()->NewStringFromAsciiChecked(buffer); |
825 } | 826 } |
826 | 827 |
827 // ES6 section 20.3.4.44 Date.prototype.valueOf ( ) | |
828 BUILTIN(DatePrototypeValueOf) { | |
829 HandleScope scope(isolate); | |
830 CHECK_RECEIVER(JSDate, date, "Date.prototype.valueOf"); | |
831 return date->value(); | |
832 } | |
833 | |
834 // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ] ( hint ) | |
835 BUILTIN(DatePrototypeToPrimitive) { | |
836 HandleScope scope(isolate); | |
837 DCHECK_EQ(2, args.length()); | |
838 CHECK_RECEIVER(JSReceiver, receiver, "Date.prototype [ @@toPrimitive ]"); | |
839 Handle<Object> hint = args.at(1); | |
840 RETURN_RESULT_OR_FAILURE(isolate, JSDate::ToPrimitive(receiver, hint)); | |
841 } | |
842 | |
843 // ES6 section B.2.4.1 Date.prototype.getYear ( ) | 828 // ES6 section B.2.4.1 Date.prototype.getYear ( ) |
844 BUILTIN(DatePrototypeGetYear) { | 829 BUILTIN(DatePrototypeGetYear) { |
845 HandleScope scope(isolate); | 830 HandleScope scope(isolate); |
846 CHECK_RECEIVER(JSDate, date, "Date.prototype.getYear"); | 831 CHECK_RECEIVER(JSDate, date, "Date.prototype.getYear"); |
847 double time_val = date->value()->Number(); | 832 double time_val = date->value()->Number(); |
848 if (std::isnan(time_val)) return date->value(); | 833 if (std::isnan(time_val)) return date->value(); |
849 int64_t time_ms = static_cast<int64_t>(time_val); | 834 int64_t time_ms = static_cast<int64_t>(time_val); |
850 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms); | 835 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms); |
851 int days = isolate->date_cache()->DaysFromTime(local_time_ms); | 836 int days = isolate->date_cache()->DaysFromTime(local_time_ms); |
852 int year, month, day; | 837 int year, month, day; |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 Generate_DatePrototype_GetField(&assembler, JSDate::kMonthUTC); | 1071 Generate_DatePrototype_GetField(&assembler, JSDate::kMonthUTC); |
1087 } | 1072 } |
1088 | 1073 |
1089 // static | 1074 // static |
1090 void Builtins::Generate_DatePrototypeGetUTCSeconds( | 1075 void Builtins::Generate_DatePrototypeGetUTCSeconds( |
1091 compiler::CodeAssemblerState* state) { | 1076 compiler::CodeAssemblerState* state) { |
1092 CodeStubAssembler assembler(state); | 1077 CodeStubAssembler assembler(state); |
1093 Generate_DatePrototype_GetField(&assembler, JSDate::kSecondUTC); | 1078 Generate_DatePrototype_GetField(&assembler, JSDate::kSecondUTC); |
1094 } | 1079 } |
1095 | 1080 |
| 1081 // static |
| 1082 void Builtins::Generate_DatePrototypeValueOf( |
| 1083 compiler::CodeAssemblerState* state) { |
| 1084 CodeStubAssembler assembler(state); |
| 1085 Generate_DatePrototype_GetField(&assembler, JSDate::kDateValue); |
| 1086 } |
| 1087 |
| 1088 // static |
| 1089 void Builtins::Generate_DatePrototypeToPrimitive( |
| 1090 compiler::CodeAssemblerState* state) { |
| 1091 CodeStubAssembler assembler(state); |
| 1092 typedef CodeStubAssembler::Label Label; |
| 1093 typedef compiler::Node Node; |
| 1094 |
| 1095 Node* receiver = assembler.Parameter(0); |
| 1096 Node* hint = assembler.Parameter(1); |
| 1097 Node* context = assembler.Parameter(4); |
| 1098 |
| 1099 // Check if the {receiver} is actually a JSReceiver. |
| 1100 Label receiver_is_invalid(&assembler, Label::kDeferred); |
| 1101 assembler.GotoIf(assembler.TaggedIsSmi(receiver), &receiver_is_invalid); |
| 1102 assembler.GotoUnless(assembler.IsJSReceiver(receiver), &receiver_is_invalid); |
| 1103 |
| 1104 // Dispatch to the appropriate OrdinaryToPrimitive builtin. |
| 1105 Label hint_is_number(&assembler), hint_is_string(&assembler), |
| 1106 hint_is_invalid(&assembler, Label::kDeferred); |
| 1107 |
| 1108 // Fast cases for internalized strings. |
| 1109 Node* number_string = assembler.LoadRoot(Heap::knumber_stringRootIndex); |
| 1110 assembler.GotoIf(assembler.WordEqual(hint, number_string), &hint_is_number); |
| 1111 Node* default_string = assembler.LoadRoot(Heap::kdefault_stringRootIndex); |
| 1112 assembler.GotoIf(assembler.WordEqual(hint, default_string), &hint_is_string); |
| 1113 Node* string_string = assembler.LoadRoot(Heap::kstring_stringRootIndex); |
| 1114 assembler.GotoIf(assembler.WordEqual(hint, string_string), &hint_is_string); |
| 1115 |
| 1116 // Slow-case with actual string comparisons. |
| 1117 Callable string_equal = CodeFactory::StringEqual(assembler.isolate()); |
| 1118 assembler.GotoIf(assembler.TaggedIsSmi(hint), &hint_is_invalid); |
| 1119 assembler.GotoUnless(assembler.IsString(hint), &hint_is_invalid); |
| 1120 assembler.GotoIf(assembler.WordEqual(assembler.CallStub(string_equal, context, |
| 1121 hint, number_string), |
| 1122 assembler.TrueConstant()), |
| 1123 &hint_is_number); |
| 1124 assembler.GotoIf(assembler.WordEqual(assembler.CallStub(string_equal, context, |
| 1125 hint, default_string), |
| 1126 assembler.TrueConstant()), |
| 1127 &hint_is_string); |
| 1128 assembler.GotoIf(assembler.WordEqual(assembler.CallStub(string_equal, context, |
| 1129 hint, string_string), |
| 1130 assembler.TrueConstant()), |
| 1131 &hint_is_string); |
| 1132 assembler.Goto(&hint_is_invalid); |
| 1133 |
| 1134 // Use the OrdinaryToPrimitive builtin to convert to a Number. |
| 1135 assembler.Bind(&hint_is_number); |
| 1136 { |
| 1137 Callable callable = CodeFactory::OrdinaryToPrimitive( |
| 1138 assembler.isolate(), OrdinaryToPrimitiveHint::kNumber); |
| 1139 Node* result = assembler.CallStub(callable, context, receiver); |
| 1140 assembler.Return(result); |
| 1141 } |
| 1142 |
| 1143 // Use the OrdinaryToPrimitive builtin to convert to a String. |
| 1144 assembler.Bind(&hint_is_string); |
| 1145 { |
| 1146 Callable callable = CodeFactory::OrdinaryToPrimitive( |
| 1147 assembler.isolate(), OrdinaryToPrimitiveHint::kString); |
| 1148 Node* result = assembler.CallStub(callable, context, receiver); |
| 1149 assembler.Return(result); |
| 1150 } |
| 1151 |
| 1152 // Raise a TypeError if the {hint} is invalid. |
| 1153 assembler.Bind(&hint_is_invalid); |
| 1154 { |
| 1155 Node* result = |
| 1156 assembler.CallRuntime(Runtime::kThrowInvalidHint, context, hint); |
| 1157 assembler.Return(result); |
| 1158 } |
| 1159 |
| 1160 // Raise a TypeError if the {receiver} is not a JSReceiver instance. |
| 1161 assembler.Bind(&receiver_is_invalid); |
| 1162 { |
| 1163 Node* result = assembler.CallRuntime( |
| 1164 Runtime::kThrowIncompatibleMethodReceiver, context, |
| 1165 assembler.HeapConstant(assembler.factory()->NewStringFromAsciiChecked( |
| 1166 "Date.prototype [ @@toPrimitive ]", TENURED)), |
| 1167 receiver); |
| 1168 assembler.Return(result); |
| 1169 } |
| 1170 } |
| 1171 |
1096 } // namespace internal | 1172 } // namespace internal |
1097 } // namespace v8 | 1173 } // namespace v8 |
OLD | NEW |