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
3 // found in the LICENSE file.
4
5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h"
7
8 #include "src/dateparser-inl.h"
9
10 namespace v8 {
11 namespace internal {
12
13 // -----------------------------------------------------------------------------
14 // ES6 section 20.3 Date Objects
15
16 namespace {
17
18 // ES6 section 20.3.1.1 Time Values and Time Range
19 const double kMinYear = -1000000.0;
20 const double kMaxYear = -kMinYear;
21 const double kMinMonth = -10000000.0;
22 const double kMaxMonth = -kMinMonth;
23
24 // 20.3.1.2 Day Number and Time within Day
25 const double kMsPerDay = 86400000.0;
26
27 // ES6 section 20.3.1.11 Hours, Minutes, Second, and Milliseconds
28 const double kMsPerSecond = 1000.0;
29 const double kMsPerMinute = 60000.0;
30 const double kMsPerHour = 3600000.0;
31
32 // ES6 section 20.3.1.14 MakeDate (day, time)
MakeDate(double day,double time)33 double MakeDate(double day, double time) {
34 if (std::isfinite(day) && std::isfinite(time)) {
35 return time + day * kMsPerDay;
36 }
37 return std::numeric_limits<double>::quiet_NaN();
38 }
39
40 // ES6 section 20.3.1.13 MakeDay (year, month, date)
MakeDay(double year,double month,double date)41 double MakeDay(double year, double month, double date) {
42 if ((kMinYear <= year && year <= kMaxYear) &&
43 (kMinMonth <= month && month <= kMaxMonth) && std::isfinite(date)) {
44 int y = FastD2I(year);
45 int m = FastD2I(month);
46 y += m / 12;
47 m %= 12;
48 if (m < 0) {
49 m += 12;
50 y -= 1;
51 }
52 DCHECK_LE(0, m);
53 DCHECK_LT(m, 12);
54
55 // kYearDelta is an arbitrary number such that:
56 // a) kYearDelta = -1 (mod 400)
57 // b) year + kYearDelta > 0 for years in the range defined by
58 // ECMA 262 - 15.9.1.1, i.e. upto 100,000,000 days on either side of
59 // Jan 1 1970. This is required so that we don't run into integer
60 // division of negative numbers.
61 // c) there shouldn't be an overflow for 32-bit integers in the following
62 // operations.
63 static const int kYearDelta = 399999;
64 static const int kBaseDay =
65 365 * (1970 + kYearDelta) + (1970 + kYearDelta) / 4 -
66 (1970 + kYearDelta) / 100 + (1970 + kYearDelta) / 400;
67 int day_from_year = 365 * (y + kYearDelta) + (y + kYearDelta) / 4 -
68 (y + kYearDelta) / 100 + (y + kYearDelta) / 400 -
69 kBaseDay;
70 if ((y % 4 != 0) || (y % 100 == 0 && y % 400 != 0)) {
71 static const int kDayFromMonth[] = {0, 31, 59, 90, 120, 151,
72 181, 212, 243, 273, 304, 334};
73 day_from_year += kDayFromMonth[m];
74 } else {
75 static const int kDayFromMonth[] = {0, 31, 60, 91, 121, 152,
76 182, 213, 244, 274, 305, 335};
77 day_from_year += kDayFromMonth[m];
78 }
79 return static_cast<double>(day_from_year - 1) + date;
80 }
81 return std::numeric_limits<double>::quiet_NaN();
82 }
83
84 // ES6 section 20.3.1.12 MakeTime (hour, min, sec, ms)
MakeTime(double hour,double min,double sec,double ms)85 double MakeTime(double hour, double min, double sec, double ms) {
86 if (std::isfinite(hour) && std::isfinite(min) && std::isfinite(sec) &&
87 std::isfinite(ms)) {
88 double const h = DoubleToInteger(hour);
89 double const m = DoubleToInteger(min);
90 double const s = DoubleToInteger(sec);
91 double const milli = DoubleToInteger(ms);
92 return h * kMsPerHour + m * kMsPerMinute + s * kMsPerSecond + milli;
93 }
94 return std::numeric_limits<double>::quiet_NaN();
95 }
96
97 // ES6 section 20.3.1.15 TimeClip (time)
TimeClip(double time)98 double TimeClip(double time) {
99 if (-DateCache::kMaxTimeInMs <= time && time <= DateCache::kMaxTimeInMs) {
100 return DoubleToInteger(time) + 0.0;
101 }
102 return std::numeric_limits<double>::quiet_NaN();
103 }
104
105 const char* kShortWeekDays[] = {"Sun", "Mon", "Tue", "Wed",
106 "Thu", "Fri", "Sat"};
107 const char* kShortMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
108 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
109
110 // ES6 section 20.3.1.16 Date Time String Format
ParseDateTimeString(Handle<String> str)111 double ParseDateTimeString(Handle<String> str) {
112 Isolate* const isolate = str->GetIsolate();
113 str = String::Flatten(str);
114 // TODO(bmeurer): Change DateParser to not use the FixedArray.
115 Handle<FixedArray> tmp =
116 isolate->factory()->NewFixedArray(DateParser::OUTPUT_SIZE);
117 DisallowHeapAllocation no_gc;
118 String::FlatContent str_content = str->GetFlatContent();
119 bool result;
120 if (str_content.IsOneByte()) {
121 result = DateParser::Parse(isolate, str_content.ToOneByteVector(), *tmp);
122 } else {
123 result = DateParser::Parse(isolate, str_content.ToUC16Vector(), *tmp);
124 }
125 if (!result) return std::numeric_limits<double>::quiet_NaN();
126 double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(),
127 tmp->get(2)->Number());
128 double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(),
129 tmp->get(5)->Number(), tmp->get(6)->Number());
130 double date = MakeDate(day, time);
131 if (tmp->get(7)->IsNull(isolate)) {
132 if (!std::isnan(date)) {
133 date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date));
134 }
135 } else {
136 date -= tmp->get(7)->Number() * 1000.0;
137 }
138 return date;
139 }
140
141 enum ToDateStringMode { kDateOnly, kTimeOnly, kDateAndTime };
142
143 // ES6 section 20.3.4.41.1 ToDateString(tv)
ToDateString(double time_val,Vector<char> str,DateCache * date_cache,ToDateStringMode mode=kDateAndTime)144 void ToDateString(double time_val, Vector<char> str, DateCache* date_cache,
145 ToDateStringMode mode = kDateAndTime) {
146 if (std::isnan(time_val)) {
147 SNPrintF(str, "Invalid Date");
148 return;
149 }
150 int64_t time_ms = static_cast<int64_t>(time_val);
151 int64_t local_time_ms = date_cache->ToLocal(time_ms);
152 int year, month, day, weekday, hour, min, sec, ms;
153 date_cache->BreakDownTime(local_time_ms, &year, &month, &day, &weekday, &hour,
154 &min, &sec, &ms);
155 int timezone_offset = -date_cache->TimezoneOffset(time_ms);
156 int timezone_hour = std::abs(timezone_offset) / 60;
157 int timezone_min = std::abs(timezone_offset) % 60;
158 const char* local_timezone = date_cache->LocalTimezone(time_ms);
159 switch (mode) {
160 case kDateOnly:
161 SNPrintF(str, "%s %s %02d %4d", kShortWeekDays[weekday],
162 kShortMonths[month], day, year);
163 return;
164 case kTimeOnly:
165 SNPrintF(str, "%02d:%02d:%02d GMT%c%02d%02d (%s)", hour, min, sec,
166 (timezone_offset < 0) ? '-' : '+', timezone_hour, timezone_min,
167 local_timezone);
168 return;
169 case kDateAndTime:
170 SNPrintF(str, "%s %s %02d %4d %02d:%02d:%02d GMT%c%02d%02d (%s)",
171 kShortWeekDays[weekday], kShortMonths[month], day, year, hour,
172 min, sec, (timezone_offset < 0) ? '-' : '+', timezone_hour,
173 timezone_min, local_timezone);
174 return;
175 }
176 UNREACHABLE();
177 }
178
SetLocalDateValue(Handle<JSDate> date,double time_val)179 Object* SetLocalDateValue(Handle<JSDate> date, double time_val) {
180 if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
181 time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
182 Isolate* const isolate = date->GetIsolate();
183 time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
184 } else {
185 time_val = std::numeric_limits<double>::quiet_NaN();
186 }
187 return *JSDate::SetValue(date, TimeClip(time_val));
188 }
189
190 } // namespace
191
192 // ES6 section 20.3.2 The Date Constructor for the [[Call]] case.
BUILTIN(DateConstructor)193 BUILTIN(DateConstructor) {
194 HandleScope scope(isolate);
195 double const time_val = JSDate::CurrentTimeValue(isolate);
196 char buffer[128];
197 ToDateString(time_val, ArrayVector(buffer), isolate->date_cache());
198 RETURN_RESULT_OR_FAILURE(
199 isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
200 }
201
202 // ES6 section 20.3.2 The Date Constructor for the [[Construct]] case.
BUILTIN(DateConstructor_ConstructStub)203 BUILTIN(DateConstructor_ConstructStub) {
204 HandleScope scope(isolate);
205 int const argc = args.length() - 1;
206 Handle<JSFunction> target = args.target();
207 Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
208 double time_val;
209 if (argc == 0) {
210 time_val = JSDate::CurrentTimeValue(isolate);
211 } else if (argc == 1) {
212 Handle<Object> value = args.at<Object>(1);
213 if (value->IsJSDate()) {
214 time_val = Handle<JSDate>::cast(value)->value()->Number();
215 } else {
216 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
217 Object::ToPrimitive(value));
218 if (value->IsString()) {
219 time_val = ParseDateTimeString(Handle<String>::cast(value));
220 } else {
221 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
222 Object::ToNumber(value));
223 time_val = value->Number();
224 }
225 }
226 } else {
227 Handle<Object> year_object;
228 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
229 Object::ToNumber(args.at<Object>(1)));
230 Handle<Object> month_object;
231 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
232 Object::ToNumber(args.at<Object>(2)));
233 double year = year_object->Number();
234 double month = month_object->Number();
235 double date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0, ms = 0.0;
236 if (argc >= 3) {
237 Handle<Object> date_object;
238 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date_object,
239 Object::ToNumber(args.at<Object>(3)));
240 date = date_object->Number();
241 if (argc >= 4) {
242 Handle<Object> hours_object;
243 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
244 isolate, hours_object, Object::ToNumber(args.at<Object>(4)));
245 hours = hours_object->Number();
246 if (argc >= 5) {
247 Handle<Object> minutes_object;
248 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
249 isolate, minutes_object, Object::ToNumber(args.at<Object>(5)));
250 minutes = minutes_object->Number();
251 if (argc >= 6) {
252 Handle<Object> seconds_object;
253 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
254 isolate, seconds_object, Object::ToNumber(args.at<Object>(6)));
255 seconds = seconds_object->Number();
256 if (argc >= 7) {
257 Handle<Object> ms_object;
258 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
259 isolate, ms_object, Object::ToNumber(args.at<Object>(7)));
260 ms = ms_object->Number();
261 }
262 }
263 }
264 }
265 }
266 if (!std::isnan(year)) {
267 double const y = DoubleToInteger(year);
268 if (0.0 <= y && y <= 99) year = 1900 + y;
269 }
270 double const day = MakeDay(year, month, date);
271 double const time = MakeTime(hours, minutes, seconds, ms);
272 time_val = MakeDate(day, time);
273 if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
274 time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
275 time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
276 } else {
277 time_val = std::numeric_limits<double>::quiet_NaN();
278 }
279 }
280 RETURN_RESULT_OR_FAILURE(isolate, JSDate::New(target, new_target, time_val));
281 }
282
283 // ES6 section 20.3.3.1 Date.now ( )
BUILTIN(DateNow)284 BUILTIN(DateNow) {
285 HandleScope scope(isolate);
286 return *isolate->factory()->NewNumber(JSDate::CurrentTimeValue(isolate));
287 }
288
289 // ES6 section 20.3.3.2 Date.parse ( string )
BUILTIN(DateParse)290 BUILTIN(DateParse) {
291 HandleScope scope(isolate);
292 Handle<String> string;
293 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
294 isolate, string,
295 Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
296 return *isolate->factory()->NewNumber(ParseDateTimeString(string));
297 }
298
299 // ES6 section 20.3.3.4 Date.UTC (year,month,date,hours,minutes,seconds,ms)
BUILTIN(DateUTC)300 BUILTIN(DateUTC) {
301 HandleScope scope(isolate);
302 int const argc = args.length() - 1;
303 double year = std::numeric_limits<double>::quiet_NaN();
304 double month = std::numeric_limits<double>::quiet_NaN();
305 double date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0, ms = 0.0;
306 if (argc >= 1) {
307 Handle<Object> year_object;
308 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
309 Object::ToNumber(args.at<Object>(1)));
310 year = year_object->Number();
311 if (argc >= 2) {
312 Handle<Object> month_object;
313 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
314 Object::ToNumber(args.at<Object>(2)));
315 month = month_object->Number();
316 if (argc >= 3) {
317 Handle<Object> date_object;
318 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
319 isolate, date_object, Object::ToNumber(args.at<Object>(3)));
320 date = date_object->Number();
321 if (argc >= 4) {
322 Handle<Object> hours_object;
323 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
324 isolate, hours_object, Object::ToNumber(args.at<Object>(4)));
325 hours = hours_object->Number();
326 if (argc >= 5) {
327 Handle<Object> minutes_object;
328 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
329 isolate, minutes_object, Object::ToNumber(args.at<Object>(5)));
330 minutes = minutes_object->Number();
331 if (argc >= 6) {
332 Handle<Object> seconds_object;
333 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
334 isolate, seconds_object,
335 Object::ToNumber(args.at<Object>(6)));
336 seconds = seconds_object->Number();
337 if (argc >= 7) {
338 Handle<Object> ms_object;
339 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
340 isolate, ms_object, Object::ToNumber(args.at<Object>(7)));
341 ms = ms_object->Number();
342 }
343 }
344 }
345 }
346 }
347 }
348 }
349 if (!std::isnan(year)) {
350 double const y = DoubleToInteger(year);
351 if (0.0 <= y && y <= 99) year = 1900 + y;
352 }
353 double const day = MakeDay(year, month, date);
354 double const time = MakeTime(hours, minutes, seconds, ms);
355 return *isolate->factory()->NewNumber(TimeClip(MakeDate(day, time)));
356 }
357
358 // ES6 section 20.3.4.20 Date.prototype.setDate ( date )
BUILTIN(DatePrototypeSetDate)359 BUILTIN(DatePrototypeSetDate) {
360 HandleScope scope(isolate);
361 CHECK_RECEIVER(JSDate, date, "Date.prototype.setDate");
362 Handle<Object> value = args.atOrUndefined(isolate, 1);
363 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
364 double time_val = date->value()->Number();
365 if (!std::isnan(time_val)) {
366 int64_t const time_ms = static_cast<int64_t>(time_val);
367 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
368 int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
369 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
370 int year, month, day;
371 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
372 time_val = MakeDate(MakeDay(year, month, value->Number()), time_within_day);
373 }
374 return SetLocalDateValue(date, time_val);
375 }
376
377 // ES6 section 20.3.4.21 Date.prototype.setFullYear (year, month, date)
BUILTIN(DatePrototypeSetFullYear)378 BUILTIN(DatePrototypeSetFullYear) {
379 HandleScope scope(isolate);
380 CHECK_RECEIVER(JSDate, date, "Date.prototype.setFullYear");
381 int const argc = args.length() - 1;
382 Handle<Object> year = args.atOrUndefined(isolate, 1);
383 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
384 double y = year->Number(), m = 0.0, dt = 1.0;
385 int time_within_day = 0;
386 if (!std::isnan(date->value()->Number())) {
387 int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
388 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
389 int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
390 time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
391 int year, month, day;
392 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
393 m = month;
394 dt = day;
395 }
396 if (argc >= 2) {
397 Handle<Object> month = args.at<Object>(2);
398 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
399 m = month->Number();
400 if (argc >= 3) {
401 Handle<Object> date = args.at<Object>(3);
402 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
403 dt = date->Number();
404 }
405 }
406 double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
407 return SetLocalDateValue(date, time_val);
408 }
409
410 // ES6 section 20.3.4.22 Date.prototype.setHours(hour, min, sec, ms)
BUILTIN(DatePrototypeSetHours)411 BUILTIN(DatePrototypeSetHours) {
412 HandleScope scope(isolate);
413 CHECK_RECEIVER(JSDate, date, "Date.prototype.setHours");
414 int const argc = args.length() - 1;
415 Handle<Object> hour = args.atOrUndefined(isolate, 1);
416 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour, Object::ToNumber(hour));
417 double h = hour->Number();
418 double time_val = date->value()->Number();
419 if (!std::isnan(time_val)) {
420 int64_t const time_ms = static_cast<int64_t>(time_val);
421 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
422 int day = isolate->date_cache()->DaysFromTime(local_time_ms);
423 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
424 double m = (time_within_day / (60 * 1000)) % 60;
425 double s = (time_within_day / 1000) % 60;
426 double milli = time_within_day % 1000;
427 if (argc >= 2) {
428 Handle<Object> min = args.at<Object>(2);
429 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
430 m = min->Number();
431 if (argc >= 3) {
432 Handle<Object> sec = args.at<Object>(3);
433 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
434 s = sec->Number();
435 if (argc >= 4) {
436 Handle<Object> ms = args.at<Object>(4);
437 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
438 milli = ms->Number();
439 }
440 }
441 }
442 time_val = MakeDate(day, MakeTime(h, m, s, milli));
443 }
444 return SetLocalDateValue(date, time_val);
445 }
446
447 // ES6 section 20.3.4.23 Date.prototype.setMilliseconds(ms)
BUILTIN(DatePrototypeSetMilliseconds)448 BUILTIN(DatePrototypeSetMilliseconds) {
449 HandleScope scope(isolate);
450 CHECK_RECEIVER(JSDate, date, "Date.prototype.setMilliseconds");
451 Handle<Object> ms = args.atOrUndefined(isolate, 1);
452 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
453 double time_val = date->value()->Number();
454 if (!std::isnan(time_val)) {
455 int64_t const time_ms = static_cast<int64_t>(time_val);
456 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
457 int day = isolate->date_cache()->DaysFromTime(local_time_ms);
458 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
459 int h = time_within_day / (60 * 60 * 1000);
460 int m = (time_within_day / (60 * 1000)) % 60;
461 int s = (time_within_day / 1000) % 60;
462 time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
463 }
464 return SetLocalDateValue(date, time_val);
465 }
466
467 // ES6 section 20.3.4.24 Date.prototype.setMinutes ( min, sec, ms )
BUILTIN(DatePrototypeSetMinutes)468 BUILTIN(DatePrototypeSetMinutes) {
469 HandleScope scope(isolate);
470 CHECK_RECEIVER(JSDate, date, "Date.prototype.setMinutes");
471 int const argc = args.length() - 1;
472 Handle<Object> min = args.atOrUndefined(isolate, 1);
473 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
474 double time_val = date->value()->Number();
475 if (!std::isnan(time_val)) {
476 int64_t const time_ms = static_cast<int64_t>(time_val);
477 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
478 int day = isolate->date_cache()->DaysFromTime(local_time_ms);
479 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
480 int h = time_within_day / (60 * 60 * 1000);
481 double m = min->Number();
482 double s = (time_within_day / 1000) % 60;
483 double milli = time_within_day % 1000;
484 if (argc >= 2) {
485 Handle<Object> sec = args.at<Object>(2);
486 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
487 s = sec->Number();
488 if (argc >= 3) {
489 Handle<Object> ms = args.at<Object>(3);
490 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
491 milli = ms->Number();
492 }
493 }
494 time_val = MakeDate(day, MakeTime(h, m, s, milli));
495 }
496 return SetLocalDateValue(date, time_val);
497 }
498
499 // ES6 section 20.3.4.25 Date.prototype.setMonth ( month, date )
BUILTIN(DatePrototypeSetMonth)500 BUILTIN(DatePrototypeSetMonth) {
501 HandleScope scope(isolate);
502 CHECK_RECEIVER(JSDate, date, "Date.prototype.setMonth");
503 int const argc = args.length() - 1;
504 Handle<Object> month = args.atOrUndefined(isolate, 1);
505 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
506 double time_val = date->value()->Number();
507 if (!std::isnan(time_val)) {
508 int64_t const time_ms = static_cast<int64_t>(time_val);
509 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
510 int days = isolate->date_cache()->DaysFromTime(local_time_ms);
511 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
512 int year, unused, day;
513 isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
514 double m = month->Number();
515 double dt = day;
516 if (argc >= 2) {
517 Handle<Object> date = args.at<Object>(2);
518 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
519 dt = date->Number();
520 }
521 time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
522 }
523 return SetLocalDateValue(date, time_val);
524 }
525
526 // ES6 section 20.3.4.26 Date.prototype.setSeconds ( sec, ms )
BUILTIN(DatePrototypeSetSeconds)527 BUILTIN(DatePrototypeSetSeconds) {
528 HandleScope scope(isolate);
529 CHECK_RECEIVER(JSDate, date, "Date.prototype.setSeconds");
530 int const argc = args.length() - 1;
531 Handle<Object> sec = args.atOrUndefined(isolate, 1);
532 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
533 double time_val = date->value()->Number();
534 if (!std::isnan(time_val)) {
535 int64_t const time_ms = static_cast<int64_t>(time_val);
536 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
537 int day = isolate->date_cache()->DaysFromTime(local_time_ms);
538 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
539 int h = time_within_day / (60 * 60 * 1000);
540 double m = (time_within_day / (60 * 1000)) % 60;
541 double s = sec->Number();
542 double milli = time_within_day % 1000;
543 if (argc >= 2) {
544 Handle<Object> ms = args.at<Object>(2);
545 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
546 milli = ms->Number();
547 }
548 time_val = MakeDate(day, MakeTime(h, m, s, milli));
549 }
550 return SetLocalDateValue(date, time_val);
551 }
552
553 // ES6 section 20.3.4.27 Date.prototype.setTime ( time )
BUILTIN(DatePrototypeSetTime)554 BUILTIN(DatePrototypeSetTime) {
555 HandleScope scope(isolate);
556 CHECK_RECEIVER(JSDate, date, "Date.prototype.setTime");
557 Handle<Object> value = args.atOrUndefined(isolate, 1);
558 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
559 return *JSDate::SetValue(date, TimeClip(value->Number()));
560 }
561
562 // ES6 section 20.3.4.28 Date.prototype.setUTCDate ( date )
BUILTIN(DatePrototypeSetUTCDate)563 BUILTIN(DatePrototypeSetUTCDate) {
564 HandleScope scope(isolate);
565 CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCDate");
566 Handle<Object> value = args.atOrUndefined(isolate, 1);
567 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
568 if (std::isnan(date->value()->Number())) return date->value();
569 int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
570 int const days = isolate->date_cache()->DaysFromTime(time_ms);
571 int const time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
572 int year, month, day;
573 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
574 double const time_val =
575 MakeDate(MakeDay(year, month, value->Number()), time_within_day);
576 return *JSDate::SetValue(date, TimeClip(time_val));
577 }
578
579 // ES6 section 20.3.4.29 Date.prototype.setUTCFullYear (year, month, date)
BUILTIN(DatePrototypeSetUTCFullYear)580 BUILTIN(DatePrototypeSetUTCFullYear) {
581 HandleScope scope(isolate);
582 CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCFullYear");
583 int const argc = args.length() - 1;
584 Handle<Object> year = args.atOrUndefined(isolate, 1);
585 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
586 double y = year->Number(), m = 0.0, dt = 1.0;
587 int time_within_day = 0;
588 if (!std::isnan(date->value()->Number())) {
589 int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
590 int const days = isolate->date_cache()->DaysFromTime(time_ms);
591 time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
592 int year, month, day;
593 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
594 m = month;
595 dt = day;
596 }
597 if (argc >= 2) {
598 Handle<Object> month = args.at<Object>(2);
599 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
600 m = month->Number();
601 if (argc >= 3) {
602 Handle<Object> date = args.at<Object>(3);
603 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
604 dt = date->Number();
605 }
606 }
607 double const time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
608 return *JSDate::SetValue(date, TimeClip(time_val));
609 }
610
611 // ES6 section 20.3.4.30 Date.prototype.setUTCHours(hour, min, sec, ms)
BUILTIN(DatePrototypeSetUTCHours)612 BUILTIN(DatePrototypeSetUTCHours) {
613 HandleScope scope(isolate);
614 CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCHours");
615 int const argc = args.length() - 1;
616 Handle<Object> hour = args.atOrUndefined(isolate, 1);
617 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour, Object::ToNumber(hour));
618 double h = hour->Number();
619 double time_val = date->value()->Number();
620 if (!std::isnan(time_val)) {
621 int64_t const time_ms = static_cast<int64_t>(time_val);
622 int day = isolate->date_cache()->DaysFromTime(time_ms);
623 int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
624 double m = (time_within_day / (60 * 1000)) % 60;
625 double s = (time_within_day / 1000) % 60;
626 double milli = time_within_day % 1000;
627 if (argc >= 2) {
628 Handle<Object> min = args.at<Object>(2);
629 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
630 m = min->Number();
631 if (argc >= 3) {
632 Handle<Object> sec = args.at<Object>(3);
633 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
634 s = sec->Number();
635 if (argc >= 4) {
636 Handle<Object> ms = args.at<Object>(4);
637 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
638 milli = ms->Number();
639 }
640 }
641 }
642 time_val = MakeDate(day, MakeTime(h, m, s, milli));
643 }
644 return *JSDate::SetValue(date, TimeClip(time_val));
645 }
646
647 // ES6 section 20.3.4.31 Date.prototype.setUTCMilliseconds(ms)
BUILTIN(DatePrototypeSetUTCMilliseconds)648 BUILTIN(DatePrototypeSetUTCMilliseconds) {
649 HandleScope scope(isolate);
650 CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMilliseconds");
651 Handle<Object> ms = args.atOrUndefined(isolate, 1);
652 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
653 double time_val = date->value()->Number();
654 if (!std::isnan(time_val)) {
655 int64_t const time_ms = static_cast<int64_t>(time_val);
656 int day = isolate->date_cache()->DaysFromTime(time_ms);
657 int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
658 int h = time_within_day / (60 * 60 * 1000);
659 int m = (time_within_day / (60 * 1000)) % 60;
660 int s = (time_within_day / 1000) % 60;
661 time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
662 }
663 return *JSDate::SetValue(date, TimeClip(time_val));
664 }
665
666 // ES6 section 20.3.4.32 Date.prototype.setUTCMinutes ( min, sec, ms )
BUILTIN(DatePrototypeSetUTCMinutes)667 BUILTIN(DatePrototypeSetUTCMinutes) {
668 HandleScope scope(isolate);
669 CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMinutes");
670 int const argc = args.length() - 1;
671 Handle<Object> min = args.atOrUndefined(isolate, 1);
672 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
673 double time_val = date->value()->Number();
674 if (!std::isnan(time_val)) {
675 int64_t const time_ms = static_cast<int64_t>(time_val);
676 int day = isolate->date_cache()->DaysFromTime(time_ms);
677 int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
678 int h = time_within_day / (60 * 60 * 1000);
679 double m = min->Number();
680 double s = (time_within_day / 1000) % 60;
681 double milli = time_within_day % 1000;
682 if (argc >= 2) {
683 Handle<Object> sec = args.at<Object>(2);
684 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
685 s = sec->Number();
686 if (argc >= 3) {
687 Handle<Object> ms = args.at<Object>(3);
688 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
689 milli = ms->Number();
690 }
691 }
692 time_val = MakeDate(day, MakeTime(h, m, s, milli));
693 }
694 return *JSDate::SetValue(date, TimeClip(time_val));
695 }
696
697 // ES6 section 20.3.4.31 Date.prototype.setUTCMonth ( month, date )
BUILTIN(DatePrototypeSetUTCMonth)698 BUILTIN(DatePrototypeSetUTCMonth) {
699 HandleScope scope(isolate);
700 CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMonth");
701 int const argc = args.length() - 1;
702 Handle<Object> month = args.atOrUndefined(isolate, 1);
703 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
704 double time_val = date->value()->Number();
705 if (!std::isnan(time_val)) {
706 int64_t const time_ms = static_cast<int64_t>(time_val);
707 int days = isolate->date_cache()->DaysFromTime(time_ms);
708 int time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
709 int year, unused, day;
710 isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
711 double m = month->Number();
712 double dt = day;
713 if (argc >= 2) {
714 Handle<Object> date = args.at<Object>(2);
715 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
716 dt = date->Number();
717 }
718 time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
719 }
720 return *JSDate::SetValue(date, TimeClip(time_val));
721 }
722
723 // ES6 section 20.3.4.34 Date.prototype.setUTCSeconds ( sec, ms )
BUILTIN(DatePrototypeSetUTCSeconds)724 BUILTIN(DatePrototypeSetUTCSeconds) {
725 HandleScope scope(isolate);
726 CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCSeconds");
727 int const argc = args.length() - 1;
728 Handle<Object> sec = args.atOrUndefined(isolate, 1);
729 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
730 double time_val = date->value()->Number();
731 if (!std::isnan(time_val)) {
732 int64_t const time_ms = static_cast<int64_t>(time_val);
733 int day = isolate->date_cache()->DaysFromTime(time_ms);
734 int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
735 int h = time_within_day / (60 * 60 * 1000);
736 double m = (time_within_day / (60 * 1000)) % 60;
737 double s = sec->Number();
738 double milli = time_within_day % 1000;
739 if (argc >= 2) {
740 Handle<Object> ms = args.at<Object>(2);
741 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
742 milli = ms->Number();
743 }
744 time_val = MakeDate(day, MakeTime(h, m, s, milli));
745 }
746 return *JSDate::SetValue(date, TimeClip(time_val));
747 }
748
749 // ES6 section 20.3.4.35 Date.prototype.toDateString ( )
BUILTIN(DatePrototypeToDateString)750 BUILTIN(DatePrototypeToDateString) {
751 HandleScope scope(isolate);
752 CHECK_RECEIVER(JSDate, date, "Date.prototype.toDateString");
753 char buffer[128];
754 ToDateString(date->value()->Number(), ArrayVector(buffer),
755 isolate->date_cache(), kDateOnly);
756 RETURN_RESULT_OR_FAILURE(
757 isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
758 }
759
760 // ES6 section 20.3.4.36 Date.prototype.toISOString ( )
BUILTIN(DatePrototypeToISOString)761 BUILTIN(DatePrototypeToISOString) {
762 HandleScope scope(isolate);
763 CHECK_RECEIVER(JSDate, date, "Date.prototype.toISOString");
764 double const time_val = date->value()->Number();
765 if (std::isnan(time_val)) {
766 THROW_NEW_ERROR_RETURN_FAILURE(
767 isolate, NewRangeError(MessageTemplate::kInvalidTimeValue));
768 }
769 int64_t const time_ms = static_cast<int64_t>(time_val);
770 int year, month, day, weekday, hour, min, sec, ms;
771 isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
772 &hour, &min, &sec, &ms);
773 char buffer[128];
774 if (year >= 0 && year <= 9999) {
775 SNPrintF(ArrayVector(buffer), "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
776 month + 1, day, hour, min, sec, ms);
777 } else if (year < 0) {
778 SNPrintF(ArrayVector(buffer), "-%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", -year,
779 month + 1, day, hour, min, sec, ms);
780 } else {
781 SNPrintF(ArrayVector(buffer), "+%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
782 month + 1, day, hour, min, sec, ms);
783 }
784 return *isolate->factory()->NewStringFromAsciiChecked(buffer);
785 }
786
787 // ES6 section 20.3.4.41 Date.prototype.toString ( )
BUILTIN(DatePrototypeToString)788 BUILTIN(DatePrototypeToString) {
789 HandleScope scope(isolate);
790 CHECK_RECEIVER(JSDate, date, "Date.prototype.toString");
791 char buffer[128];
792 ToDateString(date->value()->Number(), ArrayVector(buffer),
793 isolate->date_cache());
794 RETURN_RESULT_OR_FAILURE(
795 isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
796 }
797
798 // ES6 section 20.3.4.42 Date.prototype.toTimeString ( )
BUILTIN(DatePrototypeToTimeString)799 BUILTIN(DatePrototypeToTimeString) {
800 HandleScope scope(isolate);
801 CHECK_RECEIVER(JSDate, date, "Date.prototype.toTimeString");
802 char buffer[128];
803 ToDateString(date->value()->Number(), ArrayVector(buffer),
804 isolate->date_cache(), kTimeOnly);
805 RETURN_RESULT_OR_FAILURE(
806 isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
807 }
808
809 // ES6 section 20.3.4.43 Date.prototype.toUTCString ( )
BUILTIN(DatePrototypeToUTCString)810 BUILTIN(DatePrototypeToUTCString) {
811 HandleScope scope(isolate);
812 CHECK_RECEIVER(JSDate, date, "Date.prototype.toUTCString");
813 double const time_val = date->value()->Number();
814 if (std::isnan(time_val)) {
815 return *isolate->factory()->NewStringFromAsciiChecked("Invalid Date");
816 }
817 char buffer[128];
818 int64_t time_ms = static_cast<int64_t>(time_val);
819 int year, month, day, weekday, hour, min, sec, ms;
820 isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
821 &hour, &min, &sec, &ms);
822 SNPrintF(ArrayVector(buffer), "%s, %02d %s %4d %02d:%02d:%02d GMT",
823 kShortWeekDays[weekday], day, kShortMonths[month], year, hour, min,
824 sec);
825 return *isolate->factory()->NewStringFromAsciiChecked(buffer);
826 }
827
828 // ES6 section 20.3.4.44 Date.prototype.valueOf ( )
BUILTIN(DatePrototypeValueOf)829 BUILTIN(DatePrototypeValueOf) {
830 HandleScope scope(isolate);
831 CHECK_RECEIVER(JSDate, date, "Date.prototype.valueOf");
832 return date->value();
833 }
834
835 // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ] ( hint )
BUILTIN(DatePrototypeToPrimitive)836 BUILTIN(DatePrototypeToPrimitive) {
837 HandleScope scope(isolate);
838 DCHECK_EQ(2, args.length());
839 CHECK_RECEIVER(JSReceiver, receiver, "Date.prototype [ @@toPrimitive ]");
840 Handle<Object> hint = args.at<Object>(1);
841 RETURN_RESULT_OR_FAILURE(isolate, JSDate::ToPrimitive(receiver, hint));
842 }
843
844 // ES6 section B.2.4.1 Date.prototype.getYear ( )
BUILTIN(DatePrototypeGetYear)845 BUILTIN(DatePrototypeGetYear) {
846 HandleScope scope(isolate);
847 CHECK_RECEIVER(JSDate, date, "Date.prototype.getYear");
848 double time_val = date->value()->Number();
849 if (std::isnan(time_val)) return date->value();
850 int64_t time_ms = static_cast<int64_t>(time_val);
851 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
852 int days = isolate->date_cache()->DaysFromTime(local_time_ms);
853 int year, month, day;
854 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
855 return Smi::FromInt(year - 1900);
856 }
857
858 // ES6 section B.2.4.2 Date.prototype.setYear ( year )
BUILTIN(DatePrototypeSetYear)859 BUILTIN(DatePrototypeSetYear) {
860 HandleScope scope(isolate);
861 CHECK_RECEIVER(JSDate, date, "Date.prototype.setYear");
862 Handle<Object> year = args.atOrUndefined(isolate, 1);
863 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
864 double m = 0.0, dt = 1.0, y = year->Number();
865 if (0.0 <= y && y <= 99.0) {
866 y = 1900.0 + DoubleToInteger(y);
867 }
868 int time_within_day = 0;
869 if (!std::isnan(date->value()->Number())) {
870 int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
871 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
872 int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
873 time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
874 int year, month, day;
875 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
876 m = month;
877 dt = day;
878 }
879 double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
880 return SetLocalDateValue(date, time_val);
881 }
882
883 // ES6 section 20.3.4.37 Date.prototype.toJSON ( key )
BUILTIN(DatePrototypeToJson)884 BUILTIN(DatePrototypeToJson) {
885 HandleScope scope(isolate);
886 Handle<Object> receiver = args.atOrUndefined(isolate, 0);
887 Handle<JSReceiver> receiver_obj;
888 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_obj,
889 Object::ToObject(isolate, receiver));
890 Handle<Object> primitive;
891 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
892 isolate, primitive,
893 Object::ToPrimitive(receiver_obj, ToPrimitiveHint::kNumber));
894 if (primitive->IsNumber() && !std::isfinite(primitive->Number())) {
895 return isolate->heap()->null_value();
896 } else {
897 Handle<String> name =
898 isolate->factory()->NewStringFromAsciiChecked("toISOString");
899 Handle<Object> function;
900 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, function,
901 Object::GetProperty(receiver_obj, name));
902 if (!function->IsCallable()) {
903 THROW_NEW_ERROR_RETURN_FAILURE(
904 isolate, NewTypeError(MessageTemplate::kCalledNonCallable, name));
905 }
906 RETURN_RESULT_OR_FAILURE(
907 isolate, Execution::Call(isolate, function, receiver_obj, 0, NULL));
908 }
909 }
910
911 // static
Generate_DatePrototype_GetField(CodeStubAssembler * assembler,int field_index)912 void Builtins::Generate_DatePrototype_GetField(CodeStubAssembler* assembler,
913 int field_index) {
914 typedef CodeStubAssembler::Label Label;
915 typedef compiler::Node Node;
916
917 Node* receiver = assembler->Parameter(0);
918 Node* context = assembler->Parameter(3);
919
920 Label receiver_not_date(assembler, Label::kDeferred);
921
922 assembler->GotoIf(assembler->TaggedIsSmi(receiver), &receiver_not_date);
923 Node* receiver_instance_type = assembler->LoadInstanceType(receiver);
924 assembler->GotoIf(
925 assembler->Word32NotEqual(receiver_instance_type,
926 assembler->Int32Constant(JS_DATE_TYPE)),
927 &receiver_not_date);
928
929 // Load the specified date field, falling back to the runtime as necessary.
930 if (field_index == JSDate::kDateValue) {
931 assembler->Return(
932 assembler->LoadObjectField(receiver, JSDate::kValueOffset));
933 } else {
934 if (field_index < JSDate::kFirstUncachedField) {
935 Label stamp_mismatch(assembler, Label::kDeferred);
936 Node* date_cache_stamp = assembler->Load(
937 MachineType::AnyTagged(),
938 assembler->ExternalConstant(
939 ExternalReference::date_cache_stamp(assembler->isolate())));
940
941 Node* cache_stamp =
942 assembler->LoadObjectField(receiver, JSDate::kCacheStampOffset);
943 assembler->GotoIf(assembler->WordNotEqual(date_cache_stamp, cache_stamp),
944 &stamp_mismatch);
945 assembler->Return(assembler->LoadObjectField(
946 receiver, JSDate::kValueOffset + field_index * kPointerSize));
947
948 assembler->Bind(&stamp_mismatch);
949 }
950
951 Node* field_index_smi = assembler->SmiConstant(Smi::FromInt(field_index));
952 Node* function = assembler->ExternalConstant(
953 ExternalReference::get_date_field_function(assembler->isolate()));
954 Node* result = assembler->CallCFunction2(
955 MachineType::AnyTagged(), MachineType::Pointer(),
956 MachineType::AnyTagged(), function, receiver, field_index_smi);
957 assembler->Return(result);
958 }
959
960 // Raise a TypeError if the receiver is not a date.
961 assembler->Bind(&receiver_not_date);
962 {
963 Node* result = assembler->CallRuntime(Runtime::kThrowNotDateError, context);
964 assembler->Return(result);
965 }
966 }
967
968 // static
Generate_DatePrototypeGetDate(CodeStubAssembler * assembler)969 void Builtins::Generate_DatePrototypeGetDate(CodeStubAssembler* assembler) {
970 Generate_DatePrototype_GetField(assembler, JSDate::kDay);
971 }
972
973 // static
Generate_DatePrototypeGetDay(CodeStubAssembler * assembler)974 void Builtins::Generate_DatePrototypeGetDay(CodeStubAssembler* assembler) {
975 Generate_DatePrototype_GetField(assembler, JSDate::kWeekday);
976 }
977
978 // static
Generate_DatePrototypeGetFullYear(CodeStubAssembler * assembler)979 void Builtins::Generate_DatePrototypeGetFullYear(CodeStubAssembler* assembler) {
980 Generate_DatePrototype_GetField(assembler, JSDate::kYear);
981 }
982
983 // static
Generate_DatePrototypeGetHours(CodeStubAssembler * assembler)984 void Builtins::Generate_DatePrototypeGetHours(CodeStubAssembler* assembler) {
985 Generate_DatePrototype_GetField(assembler, JSDate::kHour);
986 }
987
988 // static
Generate_DatePrototypeGetMilliseconds(CodeStubAssembler * assembler)989 void Builtins::Generate_DatePrototypeGetMilliseconds(
990 CodeStubAssembler* assembler) {
991 Generate_DatePrototype_GetField(assembler, JSDate::kMillisecond);
992 }
993
994 // static
Generate_DatePrototypeGetMinutes(CodeStubAssembler * assembler)995 void Builtins::Generate_DatePrototypeGetMinutes(CodeStubAssembler* assembler) {
996 Generate_DatePrototype_GetField(assembler, JSDate::kMinute);
997 }
998
999 // static
Generate_DatePrototypeGetMonth(CodeStubAssembler * assembler)1000 void Builtins::Generate_DatePrototypeGetMonth(CodeStubAssembler* assembler) {
1001 Generate_DatePrototype_GetField(assembler, JSDate::kMonth);
1002 }
1003
1004 // static
Generate_DatePrototypeGetSeconds(CodeStubAssembler * assembler)1005 void Builtins::Generate_DatePrototypeGetSeconds(CodeStubAssembler* assembler) {
1006 Generate_DatePrototype_GetField(assembler, JSDate::kSecond);
1007 }
1008
1009 // static
Generate_DatePrototypeGetTime(CodeStubAssembler * assembler)1010 void Builtins::Generate_DatePrototypeGetTime(CodeStubAssembler* assembler) {
1011 Generate_DatePrototype_GetField(assembler, JSDate::kDateValue);
1012 }
1013
1014 // static
Generate_DatePrototypeGetTimezoneOffset(CodeStubAssembler * assembler)1015 void Builtins::Generate_DatePrototypeGetTimezoneOffset(
1016 CodeStubAssembler* assembler) {
1017 Generate_DatePrototype_GetField(assembler, JSDate::kTimezoneOffset);
1018 }
1019
1020 // static
Generate_DatePrototypeGetUTCDate(CodeStubAssembler * assembler)1021 void Builtins::Generate_DatePrototypeGetUTCDate(CodeStubAssembler* assembler) {
1022 Generate_DatePrototype_GetField(assembler, JSDate::kDayUTC);
1023 }
1024
1025 // static
Generate_DatePrototypeGetUTCDay(CodeStubAssembler * assembler)1026 void Builtins::Generate_DatePrototypeGetUTCDay(CodeStubAssembler* assembler) {
1027 Generate_DatePrototype_GetField(assembler, JSDate::kWeekdayUTC);
1028 }
1029
1030 // static
Generate_DatePrototypeGetUTCFullYear(CodeStubAssembler * assembler)1031 void Builtins::Generate_DatePrototypeGetUTCFullYear(
1032 CodeStubAssembler* assembler) {
1033 Generate_DatePrototype_GetField(assembler, JSDate::kYearUTC);
1034 }
1035
1036 // static
Generate_DatePrototypeGetUTCHours(CodeStubAssembler * assembler)1037 void Builtins::Generate_DatePrototypeGetUTCHours(CodeStubAssembler* assembler) {
1038 Generate_DatePrototype_GetField(assembler, JSDate::kHourUTC);
1039 }
1040
1041 // static
Generate_DatePrototypeGetUTCMilliseconds(CodeStubAssembler * assembler)1042 void Builtins::Generate_DatePrototypeGetUTCMilliseconds(
1043 CodeStubAssembler* assembler) {
1044 Generate_DatePrototype_GetField(assembler, JSDate::kMillisecondUTC);
1045 }
1046
1047 // static
Generate_DatePrototypeGetUTCMinutes(CodeStubAssembler * assembler)1048 void Builtins::Generate_DatePrototypeGetUTCMinutes(
1049 CodeStubAssembler* assembler) {
1050 Generate_DatePrototype_GetField(assembler, JSDate::kMinuteUTC);
1051 }
1052
1053 // static
Generate_DatePrototypeGetUTCMonth(CodeStubAssembler * assembler)1054 void Builtins::Generate_DatePrototypeGetUTCMonth(CodeStubAssembler* assembler) {
1055 Generate_DatePrototype_GetField(assembler, JSDate::kMonthUTC);
1056 }
1057
1058 // static
Generate_DatePrototypeGetUTCSeconds(CodeStubAssembler * assembler)1059 void Builtins::Generate_DatePrototypeGetUTCSeconds(
1060 CodeStubAssembler* assembler) {
1061 Generate_DatePrototype_GetField(assembler, JSDate::kSecondUTC);
1062 }
1063
1064 } // namespace internal
1065 } // namespace v8
1066