LCOV - code coverage report
Current view: top level - src/builtins - builtins-date.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 383 388 98.7 %
Date: 2019-04-19 Functions: 70 100 70.0 %

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

Generated by: LCOV version 1.10