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