• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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