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