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-utils.h"
662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/builtins/builtins.h"
762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/code-factory.h"
862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/code-stub-assembler.h"
962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/conversions.h"
1062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/counters.h"
11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/dateparser-inl.h"
1262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h"
13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace v8 {
15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace internal {
16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// -----------------------------------------------------------------------------
18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3 Date Objects
19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace {
21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.1.1 Time Values and Time Range
23f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst double kMinYear = -1000000.0;
24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst double kMaxYear = -kMinYear;
25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst double kMinMonth = -10000000.0;
26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst double kMaxMonth = -kMinMonth;
27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// 20.3.1.2 Day Number and Time within Day
29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst double kMsPerDay = 86400000.0;
30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.1.11 Hours, Minutes, Second, and Milliseconds
32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst double kMsPerSecond = 1000.0;
33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst double kMsPerMinute = 60000.0;
34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst double kMsPerHour = 3600000.0;
35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.1.14 MakeDate (day, time)
37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochdouble MakeDate(double day, double time) {
38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (std::isfinite(day) && std::isfinite(time)) {
39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return time + day * kMsPerDay;
40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return std::numeric_limits<double>::quiet_NaN();
42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.1.13 MakeDay (year, month, date)
45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochdouble MakeDay(double year, double month, double date) {
46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if ((kMinYear <= year && year <= kMaxYear) &&
47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      (kMinMonth <= month && month <= kMaxMonth) && std::isfinite(date)) {
48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int y = FastD2I(year);
49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int m = FastD2I(month);
50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    y += m / 12;
51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    m %= 12;
52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (m < 0) {
53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      m += 12;
54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      y -= 1;
55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_LE(0, m);
57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_LT(m, 12);
58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // kYearDelta is an arbitrary number such that:
60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // a) kYearDelta = -1 (mod 400)
61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // b) year + kYearDelta > 0 for years in the range defined by
62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    //    ECMA 262 - 15.9.1.1, i.e. upto 100,000,000 days on either side of
63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    //    Jan 1 1970. This is required so that we don't run into integer
64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    //    division of negative numbers.
65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // c) there shouldn't be an overflow for 32-bit integers in the following
66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    //    operations.
67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    static const int kYearDelta = 399999;
68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    static const int kBaseDay =
69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        365 * (1970 + kYearDelta) + (1970 + kYearDelta) / 4 -
70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        (1970 + kYearDelta) / 100 + (1970 + kYearDelta) / 400;
71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int day_from_year = 365 * (y + kYearDelta) + (y + kYearDelta) / 4 -
72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        (y + kYearDelta) / 100 + (y + kYearDelta) / 400 -
73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        kBaseDay;
74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if ((y % 4 != 0) || (y % 100 == 0 && y % 400 != 0)) {
75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      static const int kDayFromMonth[] = {0,   31,  59,  90,  120, 151,
76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                          181, 212, 243, 273, 304, 334};
77f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      day_from_year += kDayFromMonth[m];
78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {
79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      static const int kDayFromMonth[] = {0,   31,  60,  91,  121, 152,
80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                          182, 213, 244, 274, 305, 335};
81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      day_from_year += kDayFromMonth[m];
82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
83f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return static_cast<double>(day_from_year - 1) + date;
84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
85f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return std::numeric_limits<double>::quiet_NaN();
86f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
88f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.1.12 MakeTime (hour, min, sec, ms)
89f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochdouble MakeTime(double hour, double min, double sec, double ms) {
90f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (std::isfinite(hour) && std::isfinite(min) && std::isfinite(sec) &&
91f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      std::isfinite(ms)) {
92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double const h = DoubleToInteger(hour);
93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double const m = DoubleToInteger(min);
94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double const s = DoubleToInteger(sec);
95f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double const milli = DoubleToInteger(ms);
96f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return h * kMsPerHour + m * kMsPerMinute + s * kMsPerSecond + milli;
97f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
98f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return std::numeric_limits<double>::quiet_NaN();
99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.1.15 TimeClip (time)
102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochdouble TimeClip(double time) {
103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (-DateCache::kMaxTimeInMs <= time && time <= DateCache::kMaxTimeInMs) {
104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return DoubleToInteger(time) + 0.0;
105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return std::numeric_limits<double>::quiet_NaN();
107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst char* kShortWeekDays[] = {"Sun", "Mon", "Tue", "Wed",
110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                "Thu", "Fri", "Sat"};
111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst char* kShortMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.1.16 Date Time String Format
115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochdouble ParseDateTimeString(Handle<String> str) {
116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Isolate* const isolate = str->GetIsolate();
117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  str = String::Flatten(str);
118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // TODO(bmeurer): Change DateParser to not use the FixedArray.
119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<FixedArray> tmp =
120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate->factory()->NewFixedArray(DateParser::OUTPUT_SIZE);
121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DisallowHeapAllocation no_gc;
122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  String::FlatContent str_content = str->GetFlatContent();
123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool result;
124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (str_content.IsOneByte()) {
125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    result = DateParser::Parse(isolate, str_content.ToOneByteVector(), *tmp);
126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    result = DateParser::Parse(isolate, str_content.ToUC16Vector(), *tmp);
128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!result) return std::numeric_limits<double>::quiet_NaN();
130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(),
131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             tmp->get(2)->Number());
132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(),
133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               tmp->get(5)->Number(), tmp->get(6)->Number());
134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double date = MakeDate(day, time);
135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (tmp->get(7)->IsNull(isolate)) {
136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (!std::isnan(date)) {
137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date));
138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    date -= tmp->get(7)->Number() * 1000.0;
141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return date;
143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochenum ToDateStringMode { kDateOnly, kTimeOnly, kDateAndTime };
146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.41.1 ToDateString(tv)
148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ToDateString(double time_val, Vector<char> str, DateCache* date_cache,
149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                  ToDateStringMode mode = kDateAndTime) {
150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (std::isnan(time_val)) {
151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    SNPrintF(str, "Invalid Date");
152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return;
153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int64_t time_ms = static_cast<int64_t>(time_val);
155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int64_t local_time_ms = date_cache->ToLocal(time_ms);
156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int year, month, day, weekday, hour, min, sec, ms;
157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  date_cache->BreakDownTime(local_time_ms, &year, &month, &day, &weekday, &hour,
158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                            &min, &sec, &ms);
159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int timezone_offset = -date_cache->TimezoneOffset(time_ms);
160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int timezone_hour = std::abs(timezone_offset) / 60;
161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int timezone_min = std::abs(timezone_offset) % 60;
162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const char* local_timezone = date_cache->LocalTimezone(time_ms);
163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  switch (mode) {
164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kDateOnly:
165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      SNPrintF(str, "%s %s %02d %4d", kShortWeekDays[weekday],
166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               kShortMonths[month], day, year);
167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return;
168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kTimeOnly:
169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      SNPrintF(str, "%02d:%02d:%02d GMT%c%02d%02d (%s)", hour, min, sec,
170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               (timezone_offset < 0) ? '-' : '+', timezone_hour, timezone_min,
171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               local_timezone);
172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return;
173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kDateAndTime:
174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      SNPrintF(str, "%s %s %02d %4d %02d:%02d:%02d GMT%c%02d%02d (%s)",
175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               kShortWeekDays[weekday], kShortMonths[month], day, year, hour,
176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               min, sec, (timezone_offset < 0) ? '-' : '+', timezone_hour,
177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               timezone_min, local_timezone);
178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return;
179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  UNREACHABLE();
181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* SetLocalDateValue(Handle<JSDate> date, double time_val) {
184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Isolate* const isolate = date->GetIsolate();
187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = std::numeric_limits<double>::quiet_NaN();
190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *JSDate::SetValue(date, TimeClip(time_val));
192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace
195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.2 The Date Constructor for the [[Call]] case.
197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DateConstructor) {
198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double const time_val = JSDate::CurrentTimeValue(isolate);
200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char buffer[128];
201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ToDateString(time_val, ArrayVector(buffer), isolate->date_cache());
202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RETURN_RESULT_OR_FAILURE(
203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.2 The Date Constructor for the [[Construct]] case.
207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DateConstructor_ConstructStub) {
208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
210c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<JSFunction> target = args.target();
211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val;
213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (argc == 0) {
214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = JSDate::CurrentTimeValue(isolate);
215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (argc == 1) {
21662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Handle<Object> value = args.at(1);
217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (value->IsJSDate()) {
218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      time_val = Handle<JSDate>::cast(value)->value()->Number();
219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {
220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         Object::ToPrimitive(value));
222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (value->IsString()) {
223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        time_val = ParseDateTimeString(Handle<String>::cast(value));
224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                           Object::ToNumber(value));
227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        time_val = value->Number();
228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Handle<Object> year_object;
232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       Object::ToNumber(args.at(1)));
234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Handle<Object> month_object;
235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       Object::ToNumber(args.at(2)));
237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double year = year_object->Number();
238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double month = month_object->Number();
239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0, ms = 0.0;
240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 3) {
241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Handle<Object> date_object;
242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date_object,
24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         Object::ToNumber(args.at(3)));
244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      date = date_object->Number();
245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (argc >= 4) {
246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Handle<Object> hours_object;
24762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hours_object,
24862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           Object::ToNumber(args.at(4)));
249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        hours = hours_object->Number();
250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (argc >= 5) {
251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          Handle<Object> minutes_object;
25262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, minutes_object,
25362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                             Object::ToNumber(args.at(5)));
254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          minutes = minutes_object->Number();
255f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          if (argc >= 6) {
256f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            Handle<Object> seconds_object;
25762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, seconds_object,
25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                               Object::ToNumber(args.at(6)));
259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            seconds = seconds_object->Number();
260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            if (argc >= 7) {
261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              Handle<Object> ms_object;
26262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms_object,
26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                 Object::ToNumber(args.at(7)));
264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              ms = ms_object->Number();
265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            }
266f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          }
267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (!std::isnan(year)) {
271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      double const y = DoubleToInteger(year);
272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (0.0 <= y && y <= 99) year = 1900 + y;
273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double const day = MakeDay(year, month, date);
275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double const time = MakeTime(hours, minutes, seconds, ms);
276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(day, time);
277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {
281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      time_val = std::numeric_limits<double>::quiet_NaN();
282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RETURN_RESULT_OR_FAILURE(isolate, JSDate::New(target, new_target, time_val));
285f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
287f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.3.1 Date.now ( )
288f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DateNow) {
289f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *isolate->factory()->NewNumber(JSDate::CurrentTimeValue(isolate));
291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
292f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.3.2 Date.parse ( string )
294f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DateParse) {
295f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
296f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> string;
297f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate, string,
299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *isolate->factory()->NewNumber(ParseDateTimeString(string));
301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.3.4 Date.UTC (year,month,date,hours,minutes,seconds,ms)
304f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DateUTC) {
305f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
307f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double year = std::numeric_limits<double>::quiet_NaN();
30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  double month = 0.0, date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0,
30962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch         ms = 0.0;
310f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (argc >= 1) {
311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Handle<Object> year_object;
312f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       Object::ToNumber(args.at(1)));
314f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    year = year_object->Number();
315f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 2) {
316f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Handle<Object> month_object;
317f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         Object::ToNumber(args.at(2)));
319f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      month = month_object->Number();
320f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (argc >= 3) {
321f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Handle<Object> date_object;
32262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date_object,
32362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           Object::ToNumber(args.at(3)));
324f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        date = date_object->Number();
325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (argc >= 4) {
326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          Handle<Object> hours_object;
32762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hours_object,
32862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                             Object::ToNumber(args.at(4)));
329f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          hours = hours_object->Number();
330f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          if (argc >= 5) {
331f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            Handle<Object> minutes_object;
33262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, minutes_object,
33362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                               Object::ToNumber(args.at(5)));
334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            minutes = minutes_object->Number();
335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            if (argc >= 6) {
336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              Handle<Object> seconds_object;
33762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, seconds_object,
33862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                 Object::ToNumber(args.at(6)));
339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              seconds = seconds_object->Number();
340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              if (argc >= 7) {
341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                Handle<Object> ms_object;
342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
34362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                    isolate, ms_object, Object::ToNumber(args.at(7)));
344f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                ms = ms_object->Number();
345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              }
346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            }
347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          }
348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(year)) {
353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double const y = DoubleToInteger(year);
354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (0.0 <= y && y <= 99) year = 1900 + y;
355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double const day = MakeDay(year, month, date);
357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double const time = MakeTime(hours, minutes, seconds, ms);
358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *isolate->factory()->NewNumber(TimeClip(MakeDate(day, time)));
359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.20 Date.prototype.setDate ( date )
362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetDate) {
363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setDate");
365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> value = args.atOrUndefined(isolate, 1);
366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int year, month, day;
374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(MakeDay(year, month, value->Number()), time_within_day);
376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return SetLocalDateValue(date, time_val);
378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.21 Date.prototype.setFullYear (year, month, date)
381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetFullYear) {
382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setFullYear");
384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> year = args.atOrUndefined(isolate, 1);
386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double y = year->Number(), m = 0.0, dt = 1.0;
388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int time_within_day = 0;
389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(date->value()->Number())) {
390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int year, month, day;
395f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    m = month;
397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    dt = day;
398f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
399f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (argc >= 2) {
40062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Handle<Object> month = args.at(2);
401f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    m = month->Number();
403f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 3) {
40462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> date = args.at(3);
405f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
406f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      dt = date->Number();
407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
408f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return SetLocalDateValue(date, time_val);
411f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
412f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
413f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.22 Date.prototype.setHours(hour, min, sec, ms)
414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetHours) {
415f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setHours");
417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> hour = args.atOrUndefined(isolate, 1);
419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour, Object::ToNumber(hour));
420f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double h = hour->Number();
421f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
422f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
423f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
425f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int day = isolate->date_cache()->DaysFromTime(local_time_ms);
426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double m = (time_within_day / (60 * 1000)) % 60;
428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double s = (time_within_day / 1000) % 60;
429f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double milli = time_within_day % 1000;
430f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 2) {
43162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> min = args.at(2);
432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      m = min->Number();
434f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (argc >= 3) {
43562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Handle<Object> sec = args.at(3);
436f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
437f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        s = sec->Number();
438f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (argc >= 4) {
43962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Handle<Object> ms = args.at(4);
440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
441f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          milli = ms->Number();
442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
443f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
444f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
445f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(day, MakeTime(h, m, s, milli));
446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return SetLocalDateValue(date, time_val);
448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.23 Date.prototype.setMilliseconds(ms)
451f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetMilliseconds) {
452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
453f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setMilliseconds");
454f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> ms = args.atOrUndefined(isolate, 1);
455f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
456f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
457f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
458f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
459f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
460f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int day = isolate->date_cache()->DaysFromTime(local_time_ms);
461f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
462f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int h = time_within_day / (60 * 60 * 1000);
463f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int m = (time_within_day / (60 * 1000)) % 60;
464f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int s = (time_within_day / 1000) % 60;
465f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
466f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
467f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return SetLocalDateValue(date, time_val);
468f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
469f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
470f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.24 Date.prototype.setMinutes ( min, sec, ms )
471f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetMinutes) {
472f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
473f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setMinutes");
474f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> min = args.atOrUndefined(isolate, 1);
476f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
477f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int day = isolate->date_cache()->DaysFromTime(local_time_ms);
482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int h = time_within_day / (60 * 60 * 1000);
484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double m = min->Number();
485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double s = (time_within_day / 1000) % 60;
486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double milli = time_within_day % 1000;
487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 2) {
48862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> sec = args.at(2);
489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      s = sec->Number();
491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (argc >= 3) {
49262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Handle<Object> ms = args.at(3);
493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        milli = ms->Number();
495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(day, MakeTime(h, m, s, milli));
498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return SetLocalDateValue(date, time_val);
500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.25 Date.prototype.setMonth ( month, date )
503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetMonth) {
504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setMonth");
506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> month = args.atOrUndefined(isolate, 1);
508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int days = isolate->date_cache()->DaysFromTime(local_time_ms);
514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int year, unused, day;
516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double m = month->Number();
518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double dt = day;
519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 2) {
52062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> date = args.at(2);
521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      dt = date->Number();
523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
526f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return SetLocalDateValue(date, time_val);
527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.26 Date.prototype.setSeconds ( sec, ms )
530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetSeconds) {
531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setSeconds");
533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> sec = args.atOrUndefined(isolate, 1);
535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
540f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int day = isolate->date_cache()->DaysFromTime(local_time_ms);
541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
542f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int h = time_within_day / (60 * 60 * 1000);
543f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double m = (time_within_day / (60 * 1000)) % 60;
544f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double s = sec->Number();
545f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double milli = time_within_day % 1000;
546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 2) {
54762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> ms = args.at(2);
548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      milli = ms->Number();
550f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(day, MakeTime(h, m, s, milli));
552f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return SetLocalDateValue(date, time_val);
554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.27 Date.prototype.setTime ( time )
557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetTime) {
558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
559f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setTime");
560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> value = args.atOrUndefined(isolate, 1);
561f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
562f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *JSDate::SetValue(date, TimeClip(value->Number()));
563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
564f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.28 Date.prototype.setUTCDate ( date )
566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetUTCDate) {
567f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
568f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCDate");
569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> value = args.atOrUndefined(isolate, 1);
570f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
571f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (std::isnan(date->value()->Number())) return date->value();
572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const days = isolate->date_cache()->DaysFromTime(time_ms);
574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int year, month, day;
576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double const time_val =
578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MakeDate(MakeDay(year, month, value->Number()), time_within_day);
579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *JSDate::SetValue(date, TimeClip(time_val));
580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
582f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.29 Date.prototype.setUTCFullYear (year, month, date)
583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetUTCFullYear) {
584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCFullYear");
586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
587f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> year = args.atOrUndefined(isolate, 1);
588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
589f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double y = year->Number(), m = 0.0, dt = 1.0;
590f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int time_within_day = 0;
591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(date->value()->Number())) {
592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
593f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int const days = isolate->date_cache()->DaysFromTime(time_ms);
594f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
595f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int year, month, day;
596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    m = month;
598f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    dt = day;
599f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
600f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (argc >= 2) {
60162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Handle<Object> month = args.at(2);
602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    m = month->Number();
604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 3) {
60562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> date = args.at(3);
606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      dt = date->Number();
608f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
609f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
610f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double const time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
611f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *JSDate::SetValue(date, TimeClip(time_val));
612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.30 Date.prototype.setUTCHours(hour, min, sec, ms)
615f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetUTCHours) {
616f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
617f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCHours");
618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> hour = args.atOrUndefined(isolate, 1);
620f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour, Object::ToNumber(hour));
621f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double h = hour->Number();
622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
623f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int day = isolate->date_cache()->DaysFromTime(time_ms);
626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
627f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double m = (time_within_day / (60 * 1000)) % 60;
628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double s = (time_within_day / 1000) % 60;
629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double milli = time_within_day % 1000;
630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 2) {
63162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> min = args.at(2);
632f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
633f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      m = min->Number();
634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (argc >= 3) {
63562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Handle<Object> sec = args.at(3);
636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        s = sec->Number();
638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (argc >= 4) {
63962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Handle<Object> ms = args.at(4);
640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          milli = ms->Number();
642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(day, MakeTime(h, m, s, milli));
646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *JSDate::SetValue(date, TimeClip(time_val));
648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.31 Date.prototype.setUTCMilliseconds(ms)
651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetUTCMilliseconds) {
652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMilliseconds");
654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> ms = args.atOrUndefined(isolate, 1);
655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int day = isolate->date_cache()->DaysFromTime(time_ms);
660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int h = time_within_day / (60 * 60 * 1000);
662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int m = (time_within_day / (60 * 1000)) % 60;
663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int s = (time_within_day / 1000) % 60;
664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *JSDate::SetValue(date, TimeClip(time_val));
667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.32 Date.prototype.setUTCMinutes ( min, sec, ms )
670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetUTCMinutes) {
671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMinutes");
673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> min = args.atOrUndefined(isolate, 1);
675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int day = isolate->date_cache()->DaysFromTime(time_ms);
680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int h = time_within_day / (60 * 60 * 1000);
682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double m = min->Number();
683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double s = (time_within_day / 1000) % 60;
684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double milli = time_within_day % 1000;
685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 2) {
68662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> sec = args.at(2);
687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      s = sec->Number();
689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (argc >= 3) {
69062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Handle<Object> ms = args.at(3);
691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        milli = ms->Number();
693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(day, MakeTime(h, m, s, milli));
696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *JSDate::SetValue(date, TimeClip(time_val));
698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
699f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
700f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.31 Date.prototype.setUTCMonth ( month, date )
701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetUTCMonth) {
702f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
703f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMonth");
704f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
705f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> month = args.atOrUndefined(isolate, 1);
706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int days = isolate->date_cache()->DaysFromTime(time_ms);
711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int year, unused, day;
713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double m = month->Number();
715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double dt = day;
716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 2) {
71762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> date = args.at(2);
718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      dt = date->Number();
720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *JSDate::SetValue(date, TimeClip(time_val));
724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.34 Date.prototype.setUTCSeconds ( sec, ms )
727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetUTCSeconds) {
728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCSeconds");
730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const argc = args.length() - 1;
731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> sec = args.atOrUndefined(isolate, 1);
732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(time_val)) {
735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(time_val);
736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int day = isolate->date_cache()->DaysFromTime(time_ms);
737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int h = time_within_day / (60 * 60 * 1000);
739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double m = (time_within_day / (60 * 1000)) % 60;
740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double s = sec->Number();
741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    double milli = time_within_day % 1000;
742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (argc >= 2) {
74362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> ms = args.at(2);
744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      milli = ms->Number();
746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_val = MakeDate(day, MakeTime(h, m, s, milli));
748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *JSDate::SetValue(date, TimeClip(time_val));
750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.35 Date.prototype.toDateString ( )
753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeToDateString) {
754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.toDateString");
756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char buffer[128];
757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ToDateString(date->value()->Number(), ArrayVector(buffer),
758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               isolate->date_cache(), kDateOnly);
759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RETURN_RESULT_OR_FAILURE(
760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.36 Date.prototype.toISOString ( )
764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeToISOString) {
765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.toISOString");
767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double const time_val = date->value()->Number();
768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (std::isnan(time_val)) {
769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    THROW_NEW_ERROR_RETURN_FAILURE(
770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        isolate, NewRangeError(MessageTemplate::kInvalidTimeValue));
771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int64_t const time_ms = static_cast<int64_t>(time_val);
773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int year, month, day, weekday, hour, min, sec, ms;
774f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
775f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                       &hour, &min, &sec, &ms);
776f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char buffer[128];
777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (year >= 0 && year <= 9999) {
778f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    SNPrintF(ArrayVector(buffer), "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
779f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             month + 1, day, hour, min, sec, ms);
780f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (year < 0) {
781f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    SNPrintF(ArrayVector(buffer), "-%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", -year,
782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             month + 1, day, hour, min, sec, ms);
783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
784f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    SNPrintF(ArrayVector(buffer), "+%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             month + 1, day, hour, min, sec, ms);
786f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
787f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *isolate->factory()->NewStringFromAsciiChecked(buffer);
788f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
789f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
790f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.41 Date.prototype.toString ( )
791f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeToString) {
792f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
793f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.toString");
794f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char buffer[128];
795f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ToDateString(date->value()->Number(), ArrayVector(buffer),
796f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               isolate->date_cache());
797f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RETURN_RESULT_OR_FAILURE(
798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.42 Date.prototype.toTimeString ( )
802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeToTimeString) {
803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.toTimeString");
805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char buffer[128];
806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ToDateString(date->value()->Number(), ArrayVector(buffer),
807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               isolate->date_cache(), kTimeOnly);
808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RETURN_RESULT_OR_FAILURE(
809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.43 Date.prototype.toUTCString ( )
813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeToUTCString) {
814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.toUTCString");
816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double const time_val = date->value()->Number();
817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (std::isnan(time_val)) {
818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return *isolate->factory()->NewStringFromAsciiChecked("Invalid Date");
819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char buffer[128];
821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int64_t time_ms = static_cast<int64_t>(time_val);
822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int year, month, day, weekday, hour, min, sec, ms;
823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                       &hour, &min, &sec, &ms);
825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SNPrintF(ArrayVector(buffer), "%s, %02d %s %4d %02d:%02d:%02d GMT",
826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch           kShortWeekDays[weekday], day, kShortMonths[month], year, hour, min,
827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch           sec);
828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *isolate->factory()->NewStringFromAsciiChecked(buffer);
829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section B.2.4.1 Date.prototype.getYear ( )
832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeGetYear) {
833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
834f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.getYear");
835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = date->value()->Number();
836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (std::isnan(time_val)) return date->value();
837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int64_t time_ms = static_cast<int64_t>(time_val);
838f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
839f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int days = isolate->date_cache()->DaysFromTime(local_time_ms);
840f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int year, month, day;
841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
842f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return Smi::FromInt(year - 1900);
843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
844f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section B.2.4.2 Date.prototype.setYear ( year )
846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeSetYear) {
847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CHECK_RECEIVER(JSDate, date, "Date.prototype.setYear");
849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> year = args.atOrUndefined(isolate, 1);
850f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
851f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double m = 0.0, dt = 1.0, y = year->Number();
852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (0.0 <= y && y <= 99.0) {
853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    y = 1900.0 + DoubleToInteger(y);
854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int time_within_day = 0;
856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!std::isnan(date->value()->Number())) {
857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int year, month, day;
862f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
863f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    m = month;
864f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    dt = day;
865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return SetLocalDateValue(date, time_val);
868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 20.3.4.37 Date.prototype.toJSON ( key )
871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochBUILTIN(DatePrototypeToJson) {
872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandleScope scope(isolate);
873f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> receiver = args.atOrUndefined(isolate, 0);
874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<JSReceiver> receiver_obj;
875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_obj,
876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     Object::ToObject(isolate, receiver));
877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> primitive;
878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate, primitive,
880f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Object::ToPrimitive(receiver_obj, ToPrimitiveHint::kNumber));
881f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (primitive->IsNumber() && !std::isfinite(primitive->Number())) {
882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return isolate->heap()->null_value();
883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Handle<String> name =
885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        isolate->factory()->NewStringFromAsciiChecked("toISOString");
886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Handle<Object> function;
887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, function,
888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                       Object::GetProperty(receiver_obj, name));
889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (!function->IsCallable()) {
890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      THROW_NEW_ERROR_RETURN_FAILURE(
891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          isolate, NewTypeError(MessageTemplate::kCalledNonCallable, name));
892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    RETURN_RESULT_OR_FAILURE(
894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        isolate, Execution::Call(isolate, function, receiver_obj, 0, NULL));
895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
896f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
89862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace {
89962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
90062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Generate_DatePrototype_GetField(CodeStubAssembler* assembler,
90162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                     int field_index) {
902f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef CodeStubAssembler::Label Label;
903f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef compiler::Node Node;
904f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
905f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* receiver = assembler->Parameter(0);
906f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* context = assembler->Parameter(3);
907f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
908f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Label receiver_not_date(assembler, Label::kDeferred);
909f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
910c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  assembler->GotoIf(assembler->TaggedIsSmi(receiver), &receiver_not_date);
911f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* receiver_instance_type = assembler->LoadInstanceType(receiver);
912f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  assembler->GotoIf(
913f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      assembler->Word32NotEqual(receiver_instance_type,
914f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                assembler->Int32Constant(JS_DATE_TYPE)),
915f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      &receiver_not_date);
916f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
917f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Load the specified date field, falling back to the runtime as necessary.
918f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (field_index == JSDate::kDateValue) {
919f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    assembler->Return(
920f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        assembler->LoadObjectField(receiver, JSDate::kValueOffset));
921f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
922f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (field_index < JSDate::kFirstUncachedField) {
923f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Label stamp_mismatch(assembler, Label::kDeferred);
924f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Node* date_cache_stamp = assembler->Load(
925f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          MachineType::AnyTagged(),
926f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          assembler->ExternalConstant(
927f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              ExternalReference::date_cache_stamp(assembler->isolate())));
928f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
929f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Node* cache_stamp =
930f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          assembler->LoadObjectField(receiver, JSDate::kCacheStampOffset);
931f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      assembler->GotoIf(assembler->WordNotEqual(date_cache_stamp, cache_stamp),
932f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        &stamp_mismatch);
933f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      assembler->Return(assembler->LoadObjectField(
934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          receiver, JSDate::kValueOffset + field_index * kPointerSize));
935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
936f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      assembler->Bind(&stamp_mismatch);
937f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
938f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
939f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Node* field_index_smi = assembler->SmiConstant(Smi::FromInt(field_index));
940f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Node* function = assembler->ExternalConstant(
941f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ExternalReference::get_date_field_function(assembler->isolate()));
942f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Node* result = assembler->CallCFunction2(
94362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        MachineType::AnyTagged(), MachineType::AnyTagged(),
944f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        MachineType::AnyTagged(), function, receiver, field_index_smi);
945f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    assembler->Return(result);
946f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
947f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
948f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Raise a TypeError if the receiver is not a date.
949f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  assembler->Bind(&receiver_not_date);
950f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  {
95162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    assembler->CallRuntime(Runtime::kThrowNotDateError, context);
95262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    assembler->Unreachable();
953f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
954f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
955f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
95662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // namespace
95762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
958f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// static
95962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetDate(
96062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
96162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
96262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kDay);
963f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
964f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
965f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
96662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetDay(
96762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
96862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
96962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kWeekday);
970f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
971f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
972f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
97362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetFullYear(
97462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
97562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
97662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kYear);
977f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
978f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
979f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
98062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetHours(
98162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
98262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
98362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kHour);
984f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
986f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
987f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Builtins::Generate_DatePrototypeGetMilliseconds(
98862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
98962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
99062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kMillisecond);
991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
992f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
99462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetMinutes(
99562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
99662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
99762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kMinute);
998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
100162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetMonth(
100262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
100362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
100462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kMonth);
1005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
100862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetSeconds(
100962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
101062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
101162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kSecond);
1012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1014f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
101562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetTime(
101662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
101762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
101862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kDateValue);
1019f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1020f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1021f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
1022f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Builtins::Generate_DatePrototypeGetTimezoneOffset(
102362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
102462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
102562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kTimezoneOffset);
1026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1027f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1028f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
102962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetUTCDate(
103062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
103162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
103262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kDayUTC);
1033f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1034f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1035f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
103662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetUTCDay(
103762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
103862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
103962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kWeekdayUTC);
1040f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1041f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1042f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
1043f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Builtins::Generate_DatePrototypeGetUTCFullYear(
104462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
104562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
104662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kYearUTC);
1047f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1048f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1049f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
105062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetUTCHours(
105162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
105262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
105362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kHourUTC);
1054f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1055f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1056f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
1057f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Builtins::Generate_DatePrototypeGetUTCMilliseconds(
105862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
105962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
106062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kMillisecondUTC);
1061f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1062f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1063f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
1064f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Builtins::Generate_DatePrototypeGetUTCMinutes(
106562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
106662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
106762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kMinuteUTC);
1068f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1069f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1070f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
107162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeGetUTCMonth(
107262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
107362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
107462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kMonthUTC);
1075f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1076f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1077f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
1078f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Builtins::Generate_DatePrototypeGetUTCSeconds(
107962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
108062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
108162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kSecondUTC);
108262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
108362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
108462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// static
108562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeValueOf(
108662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
108762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
108862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Generate_DatePrototype_GetField(&assembler, JSDate::kDateValue);
108962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
109062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
109162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// static
109262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Builtins::Generate_DatePrototypeToPrimitive(
109362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    compiler::CodeAssemblerState* state) {
109462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubAssembler assembler(state);
109562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef CodeStubAssembler::Label Label;
109662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef compiler::Node Node;
109762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
109862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* receiver = assembler.Parameter(0);
109962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* hint = assembler.Parameter(1);
110062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = assembler.Parameter(4);
110162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
110262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Check if the {receiver} is actually a JSReceiver.
110362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label receiver_is_invalid(&assembler, Label::kDeferred);
110462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.GotoIf(assembler.TaggedIsSmi(receiver), &receiver_is_invalid);
110562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.GotoIfNot(assembler.IsJSReceiver(receiver), &receiver_is_invalid);
110662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
110762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Dispatch to the appropriate OrdinaryToPrimitive builtin.
110862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label hint_is_number(&assembler), hint_is_string(&assembler),
110962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      hint_is_invalid(&assembler, Label::kDeferred);
111062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
111162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Fast cases for internalized strings.
111262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* number_string = assembler.LoadRoot(Heap::knumber_stringRootIndex);
111362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.GotoIf(assembler.WordEqual(hint, number_string), &hint_is_number);
111462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* default_string = assembler.LoadRoot(Heap::kdefault_stringRootIndex);
111562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.GotoIf(assembler.WordEqual(hint, default_string), &hint_is_string);
111662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* string_string = assembler.LoadRoot(Heap::kstring_stringRootIndex);
111762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.GotoIf(assembler.WordEqual(hint, string_string), &hint_is_string);
111862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
111962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Slow-case with actual string comparisons.
112062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Callable string_equal = CodeFactory::StringEqual(assembler.isolate());
112162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.GotoIf(assembler.TaggedIsSmi(hint), &hint_is_invalid);
112262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.GotoIfNot(assembler.IsString(hint), &hint_is_invalid);
112362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.GotoIf(assembler.WordEqual(assembler.CallStub(string_equal, context,
112462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                          hint, number_string),
112562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       assembler.TrueConstant()),
112662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                   &hint_is_number);
112762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.GotoIf(assembler.WordEqual(assembler.CallStub(string_equal, context,
112862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                          hint, default_string),
112962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       assembler.TrueConstant()),
113062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                   &hint_is_string);
113162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.GotoIf(assembler.WordEqual(assembler.CallStub(string_equal, context,
113262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                          hint, string_string),
113362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       assembler.TrueConstant()),
113462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                   &hint_is_string);
113562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.Goto(&hint_is_invalid);
113662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
113762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Use the OrdinaryToPrimitive builtin to convert to a Number.
113862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.Bind(&hint_is_number);
113962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
114062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Callable callable = CodeFactory::OrdinaryToPrimitive(
114162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        assembler.isolate(), OrdinaryToPrimitiveHint::kNumber);
114262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* result = assembler.CallStub(callable, context, receiver);
114362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    assembler.Return(result);
114462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
114562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
114662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Use the OrdinaryToPrimitive builtin to convert to a String.
114762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.Bind(&hint_is_string);
114862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
114962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Callable callable = CodeFactory::OrdinaryToPrimitive(
115062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        assembler.isolate(), OrdinaryToPrimitiveHint::kString);
115162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* result = assembler.CallStub(callable, context, receiver);
115262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    assembler.Return(result);
115362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
115462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
115562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Raise a TypeError if the {hint} is invalid.
115662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.Bind(&hint_is_invalid);
115762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
115862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    assembler.CallRuntime(Runtime::kThrowInvalidHint, context, hint);
115962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    assembler.Unreachable();
116062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
116162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
116262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Raise a TypeError if the {receiver} is not a JSReceiver instance.
116362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  assembler.Bind(&receiver_is_invalid);
116462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
116562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    assembler.CallRuntime(
116662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Runtime::kThrowIncompatibleMethodReceiver, context,
116762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        assembler.HeapConstant(assembler.factory()->NewStringFromAsciiChecked(
116862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            "Date.prototype [ @@toPrimitive ]", TENURED)),
116962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        receiver);
117062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    assembler.Unreachable();
117162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
1172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace internal
1175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace v8
1176