Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/builtins.h" | 5 #include "src/builtins.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
| 9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
| 11 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
| 12 #include "src/dateparser-inl.h" | |
| 12 #include "src/elements.h" | 13 #include "src/elements.h" |
| 13 #include "src/frames-inl.h" | 14 #include "src/frames-inl.h" |
| 14 #include "src/gdb-jit.h" | 15 #include "src/gdb-jit.h" |
| 15 #include "src/ic/handler-compiler.h" | 16 #include "src/ic/handler-compiler.h" |
| 16 #include "src/ic/ic.h" | 17 #include "src/ic/ic.h" |
| 17 #include "src/isolate-inl.h" | 18 #include "src/isolate-inl.h" |
| 18 #include "src/messages.h" | 19 #include "src/messages.h" |
| 19 #include "src/profiler/cpu-profiler.h" | 20 #include "src/profiler/cpu-profiler.h" |
| 20 #include "src/property-descriptor.h" | 21 #include "src/property-descriptor.h" |
| 21 #include "src/prototype.h" | 22 #include "src/prototype.h" |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 name##ArgumentsType args(args_length, args_object); \ | 142 name##ArgumentsType args(args_length, args_object); \ |
| 142 return Builtin_Impl_##name(args, isolate); \ | 143 return Builtin_Impl_##name(args, isolate); \ |
| 143 } \ | 144 } \ |
| 144 MUST_USE_RESULT static Object* Builtin_Impl_##name( \ | 145 MUST_USE_RESULT static Object* Builtin_Impl_##name( \ |
| 145 name##ArgumentsType args, Isolate* isolate) | 146 name##ArgumentsType args, Isolate* isolate) |
| 146 | 147 |
| 147 | 148 |
| 148 // ---------------------------------------------------------------------------- | 149 // ---------------------------------------------------------------------------- |
| 149 | 150 |
| 150 | 151 |
| 152 #define CHECK_RECEIVER(Type, name, method) \ | |
| 153 if (!args.receiver()->Is##Type()) { \ | |
| 154 THROW_NEW_ERROR_RETURN_FAILURE( \ | |
| 155 isolate, \ | |
| 156 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \ | |
| 157 isolate->factory()->NewStringFromAsciiChecked(method), \ | |
| 158 args.receiver())); \ | |
| 159 } \ | |
| 160 Handle<Type> name = Handle<Type>::cast(args.receiver()) | |
| 161 | |
| 162 | |
| 151 inline bool ClampedToInteger(Object* object, int* out) { | 163 inline bool ClampedToInteger(Object* object, int* out) { |
| 152 // This is an extended version of ECMA-262 7.1.11 handling signed values | 164 // This is an extended version of ECMA-262 7.1.11 handling signed values |
| 153 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] | 165 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] |
| 154 if (object->IsSmi()) { | 166 if (object->IsSmi()) { |
| 155 *out = Smi::cast(object)->value(); | 167 *out = Smi::cast(object)->value(); |
| 156 return true; | 168 return true; |
| 157 } else if (object->IsHeapNumber()) { | 169 } else if (object->IsHeapNumber()) { |
| 158 double value = HeapNumber::cast(object)->value(); | 170 double value = HeapNumber::cast(object)->value(); |
| 159 if (std::isnan(value)) { | 171 if (std::isnan(value)) { |
| 160 *out = 0; | 172 *out = 0; |
| (...skipping 1770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1931 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); | 1943 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); |
| 1932 } | 1944 } |
| 1933 | 1945 |
| 1934 Maybe<bool> result = JSReceiver::SetPrototype( | 1946 Maybe<bool> result = JSReceiver::SetPrototype( |
| 1935 Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW); | 1947 Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW); |
| 1936 MAYBE_RETURN(result, isolate->heap()->exception()); | 1948 MAYBE_RETURN(result, isolate->heap()->exception()); |
| 1937 return *isolate->factory()->ToBoolean(result.FromJust()); | 1949 return *isolate->factory()->ToBoolean(result.FromJust()); |
| 1938 } | 1950 } |
| 1939 | 1951 |
| 1940 | 1952 |
| 1953 // ----------------------------------------------------------------------------- | |
| 1954 // ES6 section 20.3 Date Objects | |
| 1955 | |
| 1956 | |
| 1957 namespace { | |
| 1958 | |
| 1959 // ES6 section 20.3.1.1 Time Values and Time Range | |
| 1960 const double kMinYear = -1000000.0; | |
| 1961 const double kMaxYear = -kMinYear; | |
| 1962 const double kMinMonth = -10000000.0; | |
| 1963 const double kMaxMonth = -kMinMonth; | |
| 1964 | |
| 1965 | |
| 1966 // 20.3.1.2 Day Number and Time within Day | |
| 1967 const double kMsPerDay = 86400000.0; | |
| 1968 | |
| 1969 | |
| 1970 // ES6 section 20.3.1.11 Hours, Minutes, Second, and Milliseconds | |
| 1971 const double kMsPerSecond = 1000.0; | |
| 1972 const double kMsPerMinute = 60000.0; | |
| 1973 const double kMsPerHour = 3600000.0; | |
| 1974 | |
| 1975 | |
| 1976 // ES6 section 20.3.1.14 MakeDate (day, time) | |
| 1977 double MakeDate(double day, double time) { | |
| 1978 if (std::isfinite(day) && std::isfinite(time)) { | |
| 1979 return time + day * kMsPerDay; | |
| 1980 } | |
| 1981 return std::numeric_limits<double>::quiet_NaN(); | |
| 1982 } | |
| 1983 | |
| 1984 | |
| 1985 // ES6 section 20.3.1.13 MakeDay (year, month, date) | |
| 1986 double MakeDay(double year, double month, double date) { | |
| 1987 if ((kMinYear <= year && year <= kMaxYear) && | |
| 1988 (kMinMonth <= month && month <= kMaxMonth) && std::isfinite(date)) { | |
| 1989 int y = FastD2I(year); | |
| 1990 int m = FastD2I(month); | |
| 1991 y += m / 12; | |
| 1992 m %= 12; | |
| 1993 if (m < 0) { | |
| 1994 m += 12; | |
| 1995 y -= 1; | |
| 1996 } | |
| 1997 DCHECK_LE(0, m); | |
| 1998 DCHECK_LT(m, 12); | |
| 1999 | |
| 2000 // kYearDelta is an arbitrary number such that: | |
| 2001 // a) kYearDelta = -1 (mod 400) | |
| 2002 // b) year + kYearDelta > 0 for years in the range defined by | |
| 2003 // ECMA 262 - 15.9.1.1, i.e. upto 100,000,000 days on either side of | |
| 2004 // Jan 1 1970. This is required so that we don't run into integer | |
| 2005 // division of negative numbers. | |
| 2006 // c) there shouldn't be an overflow for 32-bit integers in the following | |
| 2007 // operations. | |
| 2008 static const int kYearDelta = 399999; | |
| 2009 static const int kBaseDay = | |
| 2010 365 * (1970 + kYearDelta) + (1970 + kYearDelta) / 4 - | |
| 2011 (1970 + kYearDelta) / 100 + (1970 + kYearDelta) / 400; | |
| 2012 int day_from_year = 365 * (y + kYearDelta) + (y + kYearDelta) / 4 - | |
| 2013 (y + kYearDelta) / 100 + (y + kYearDelta) / 400 - | |
| 2014 kBaseDay; | |
| 2015 if ((y % 4 != 0) || (y % 100 == 0 && y % 400 != 0)) { | |
| 2016 static const int kDayFromMonth[] = {0, 31, 59, 90, 120, 151, | |
| 2017 181, 212, 243, 273, 304, 334}; | |
| 2018 day_from_year += kDayFromMonth[m]; | |
| 2019 } else { | |
| 2020 static const int kDayFromMonth[] = {0, 31, 60, 91, 121, 152, | |
| 2021 182, 213, 244, 274, 305, 335}; | |
| 2022 day_from_year += kDayFromMonth[m]; | |
| 2023 } | |
| 2024 return static_cast<double>(day_from_year - 1) + date; | |
| 2025 } | |
| 2026 return std::numeric_limits<double>::quiet_NaN(); | |
| 2027 } | |
| 2028 | |
| 2029 | |
| 2030 // ES6 section 20.3.1.12 MakeTime (hour, min, sec, ms) | |
| 2031 double MakeTime(double hour, double min, double sec, double ms) { | |
| 2032 if (std::isfinite(hour) && std::isfinite(min) && std::isfinite(sec) && | |
| 2033 std::isfinite(ms)) { | |
| 2034 double const h = DoubleToInteger(hour); | |
| 2035 double const m = DoubleToInteger(min); | |
| 2036 double const s = DoubleToInteger(sec); | |
| 2037 double const milli = DoubleToInteger(ms); | |
| 2038 return h * kMsPerHour + m * kMsPerMinute + s * kMsPerSecond + milli; | |
| 2039 } | |
| 2040 return std::numeric_limits<double>::quiet_NaN(); | |
| 2041 } | |
| 2042 | |
| 2043 | |
| 2044 // ES6 section 20.3.1.15 TimeClip (time) | |
| 2045 double TimeClip(double time) { | |
| 2046 if (-DateCache::kMaxTimeInMs <= time && time <= DateCache::kMaxTimeInMs) { | |
| 2047 return DoubleToInteger(time) + 0.0; | |
| 2048 } | |
| 2049 return std::numeric_limits<double>::quiet_NaN(); | |
| 2050 } | |
| 2051 | |
| 2052 | |
| 2053 const char* kShortWeekDays[] = {"Sun", "Mon", "Tue", "Wed", | |
| 2054 "Thu", "Fri", "Sat"}; | |
| 2055 const char* kShortMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", | |
| 2056 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; | |
| 2057 | |
| 2058 | |
| 2059 // ES6 section 20.3.1.16 Date Time String Format | |
| 2060 double ParseDateTimeString(Handle<String> str) { | |
| 2061 Isolate* const isolate = str->GetIsolate(); | |
| 2062 str = String::Flatten(str); | |
| 2063 // TODO(bmeurer): Change DateParser to not use the FixedArray. | |
| 2064 Handle<FixedArray> tmp = | |
| 2065 isolate->factory()->NewFixedArray(DateParser::OUTPUT_SIZE); | |
| 2066 DisallowHeapAllocation no_gc; | |
| 2067 String::FlatContent str_content = str->GetFlatContent(); | |
| 2068 bool result; | |
| 2069 if (str_content.IsOneByte()) { | |
| 2070 result = DateParser::Parse(str_content.ToOneByteVector(), *tmp, | |
| 2071 isolate->unicode_cache()); | |
| 2072 } else { | |
| 2073 result = DateParser::Parse(str_content.ToUC16Vector(), *tmp, | |
| 2074 isolate->unicode_cache()); | |
| 2075 } | |
| 2076 if (!result) return std::numeric_limits<double>::quiet_NaN(); | |
| 2077 double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(), | |
| 2078 tmp->get(2)->Number()); | |
| 2079 double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(), | |
| 2080 tmp->get(5)->Number(), tmp->get(6)->Number()); | |
| 2081 double date = MakeDate(day, time); | |
| 2082 if (tmp->get(7)->IsNull()) { | |
| 2083 date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date)); | |
| 2084 } else { | |
| 2085 date -= tmp->get(7)->Number() * 1000.0; | |
| 2086 } | |
| 2087 return date; | |
| 2088 } | |
| 2089 | |
| 2090 | |
| 2091 // ES6 section 20.3.4.41.1 ToDateString(tv) | |
| 2092 void ToDateString(double tv, Vector<char> str, DateCache* date_cache) { | |
| 2093 if (std::isnan(tv)) { | |
| 2094 SNPrintF(str, "Invalid Date"); | |
| 2095 } else { | |
| 2096 int64_t time_ms = static_cast<int64_t>(tv); | |
| 2097 int64_t local_time_ms = date_cache->ToLocal(time_ms); | |
| 2098 int year, month, day, weekday, hour, min, sec, ms; | |
| 2099 date_cache->BreakDown(local_time_ms, &year, &month, &day, &weekday, &hour, | |
| 2100 &min, &sec, &ms); | |
| 2101 int timezone_offset = -date_cache->TimezoneOffset(time_ms); | |
| 2102 int timezone_hour = std::abs(timezone_offset) / 60; | |
| 2103 int timezone_min = std::abs(timezone_offset) % 60; | |
| 2104 const char* local_timezone = date_cache->LocalTimezone(time_ms); | |
| 2105 SNPrintF(str, "%s %s %02d %4d %02d:%02d:%02d GMT%c%02d%02d (%s)", | |
| 2106 kShortWeekDays[weekday], kShortMonths[month], day, year, hour, min, | |
| 2107 sec, (timezone_offset < 0) ? '-' : '+', timezone_hour, | |
| 2108 timezone_min, local_timezone); | |
| 2109 } | |
| 2110 } | |
| 2111 | |
| 2112 } // namespace | |
| 2113 | |
| 2114 | |
| 2115 // ES6 section 20.3.2 The Date Constructor for the [[Call]] case. | |
| 2116 BUILTIN(DateConstructor) { | |
| 2117 HandleScope scope(isolate); | |
| 2118 double const tv = JSDate::CurrentTimeValue(isolate); | |
| 2119 char buffer[128]; | |
| 2120 Vector<char> str(buffer, arraysize(buffer)); | |
| 2121 ToDateString(tv, str, isolate->date_cache()); | |
| 2122 return *isolate->factory()->NewStringFromAsciiChecked(str.start()); | |
| 2123 } | |
| 2124 | |
| 2125 | |
| 2126 // ES6 section 20.3.2 The Date Constructor for the [[Construct]] case. | |
| 2127 BUILTIN(DateConstructor_ConstructStub) { | |
| 2128 HandleScope scope(isolate); | |
| 2129 int const argc = args.length() - 1; | |
| 2130 Handle<JSFunction> target = args.target(); | |
| 2131 Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target()); | |
| 2132 double tv; | |
|
Camillo Bruni
2016/01/05 10:26:59
I'd prefer having time_value where (even though th
Benedikt Meurer
2016/01/05 10:30:59
Done.
| |
| 2133 if (argc == 0) { | |
| 2134 tv = JSDate::CurrentTimeValue(isolate); | |
| 2135 } else if (argc == 1) { | |
| 2136 Handle<Object> value = args.at<Object>(1); | |
| 2137 if (value->IsJSDate()) { | |
| 2138 tv = Handle<JSDate>::cast(value)->value()->Number(); | |
| 2139 } else { | |
| 2140 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, | |
| 2141 Object::ToPrimitive(value)); | |
| 2142 if (value->IsString()) { | |
| 2143 tv = ParseDateTimeString(Handle<String>::cast(value)); | |
| 2144 } else { | |
| 2145 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, | |
| 2146 Object::ToNumber(value)); | |
| 2147 tv = value->Number(); | |
| 2148 } | |
| 2149 } | |
| 2150 } else { | |
| 2151 Handle<Object> year_object; | |
| 2152 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object, | |
| 2153 Object::ToNumber(args.at<Object>(1))); | |
| 2154 Handle<Object> month_object; | |
| 2155 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object, | |
| 2156 Object::ToNumber(args.at<Object>(2))); | |
| 2157 double year = year_object->Number(); | |
| 2158 double month = month_object->Number(); | |
| 2159 double date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0, ms = 0.0; | |
| 2160 if (argc >= 3) { | |
| 2161 Handle<Object> date_object; | |
| 2162 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date_object, | |
| 2163 Object::ToNumber(args.at<Object>(3))); | |
| 2164 date = date_object->Number(); | |
| 2165 if (argc >= 4) { | |
| 2166 Handle<Object> hours_object; | |
| 2167 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 2168 isolate, hours_object, Object::ToNumber(args.at<Object>(4))); | |
| 2169 hours = hours_object->Number(); | |
| 2170 if (argc >= 5) { | |
| 2171 Handle<Object> minutes_object; | |
| 2172 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 2173 isolate, minutes_object, Object::ToNumber(args.at<Object>(5))); | |
| 2174 minutes = minutes_object->Number(); | |
| 2175 if (argc >= 6) { | |
| 2176 Handle<Object> seconds_object; | |
| 2177 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 2178 isolate, seconds_object, Object::ToNumber(args.at<Object>(6))); | |
| 2179 seconds = seconds_object->Number(); | |
| 2180 if (argc >= 7) { | |
| 2181 Handle<Object> ms_object; | |
| 2182 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 2183 isolate, ms_object, Object::ToNumber(args.at<Object>(7))); | |
| 2184 ms = ms_object->Number(); | |
| 2185 } | |
| 2186 } | |
| 2187 } | |
| 2188 } | |
| 2189 } | |
| 2190 if (!std::isnan(year)) { | |
| 2191 double const y = DoubleToInteger(year); | |
| 2192 if (0.0 <= y && y <= 99) year = 1900 + y; | |
| 2193 } | |
| 2194 double const day = MakeDay(year, month, date); | |
| 2195 double const time = MakeTime(hours, minutes, seconds, ms); | |
| 2196 tv = MakeDate(day, time); | |
| 2197 if (tv >= -DateCache::kMaxTimeBeforeUTCInMs && | |
| 2198 tv <= DateCache::kMaxTimeBeforeUTCInMs) { | |
| 2199 tv = isolate->date_cache()->ToUTC(static_cast<int64_t>(tv)); | |
| 2200 } else { | |
| 2201 tv = std::numeric_limits<double>::quiet_NaN(); | |
| 2202 } | |
| 2203 } | |
| 2204 Handle<JSDate> result; | |
| 2205 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | |
| 2206 JSDate::New(target, new_target, tv)); | |
| 2207 return *result; | |
| 2208 } | |
| 2209 | |
| 2210 | |
| 2211 // ES6 section 20.3.3.1 Date.now ( ) | |
| 2212 BUILTIN(DateNow) { | |
| 2213 HandleScope scope(isolate); | |
| 2214 return *isolate->factory()->NewNumber(JSDate::CurrentTimeValue(isolate)); | |
| 2215 } | |
| 2216 | |
| 2217 | |
| 2218 // ES6 section 20.3.3.2 Date.parse ( string ) | |
| 2219 BUILTIN(DateParse) { | |
| 2220 HandleScope scope(isolate); | |
| 2221 Handle<String> string; | |
| 2222 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 2223 isolate, string, | |
| 2224 Object::ToString(isolate, args.atOrUndefined(isolate, 1))); | |
| 2225 double const tv = ParseDateTimeString(string); | |
| 2226 return *isolate->factory()->NewNumber(tv); | |
| 2227 } | |
| 2228 | |
| 2229 | |
| 2230 // ES6 section 20.3.3.4 Date.UTC (year,month,date,hours,minutes,seconds,ms) | |
| 2231 BUILTIN(DateUTC) { | |
| 2232 HandleScope scope(isolate); | |
| 2233 int const argc = args.length() - 1; | |
| 2234 double year = std::numeric_limits<double>::quiet_NaN(); | |
| 2235 double month = std::numeric_limits<double>::quiet_NaN(); | |
| 2236 double date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0, ms = 0.0; | |
| 2237 if (argc >= 1) { | |
| 2238 Handle<Object> year_object; | |
| 2239 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object, | |
| 2240 Object::ToNumber(args.at<Object>(1))); | |
| 2241 year = year_object->Number(); | |
| 2242 if (argc >= 2) { | |
| 2243 Handle<Object> month_object; | |
| 2244 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object, | |
| 2245 Object::ToNumber(args.at<Object>(2))); | |
| 2246 month = month_object->Number(); | |
| 2247 if (argc >= 3) { | |
| 2248 Handle<Object> date_object; | |
| 2249 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 2250 isolate, date_object, Object::ToNumber(args.at<Object>(3))); | |
| 2251 date = date_object->Number(); | |
| 2252 if (argc >= 4) { | |
| 2253 Handle<Object> hours_object; | |
| 2254 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 2255 isolate, hours_object, Object::ToNumber(args.at<Object>(4))); | |
| 2256 hours = hours_object->Number(); | |
| 2257 if (argc >= 5) { | |
| 2258 Handle<Object> minutes_object; | |
| 2259 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 2260 isolate, minutes_object, Object::ToNumber(args.at<Object>(5))); | |
| 2261 minutes = minutes_object->Number(); | |
| 2262 if (argc >= 6) { | |
| 2263 Handle<Object> seconds_object; | |
| 2264 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 2265 isolate, seconds_object, | |
| 2266 Object::ToNumber(args.at<Object>(6))); | |
| 2267 seconds = seconds_object->Number(); | |
| 2268 if (argc >= 7) { | |
| 2269 Handle<Object> ms_object; | |
| 2270 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 2271 isolate, ms_object, Object::ToNumber(args.at<Object>(7))); | |
| 2272 ms = ms_object->Number(); | |
| 2273 } | |
| 2274 } | |
| 2275 } | |
| 2276 } | |
| 2277 } | |
| 2278 } | |
| 2279 } | |
| 2280 if (!std::isnan(year)) { | |
| 2281 double const y = DoubleToInteger(year); | |
| 2282 if (0.0 <= y && y <= 99) year = 1900 + y; | |
| 2283 } | |
| 2284 double const day = MakeDay(year, month, date); | |
| 2285 double const time = MakeTime(hours, minutes, seconds, ms); | |
| 2286 return *isolate->factory()->NewNumber(TimeClip(MakeDate(day, time))); | |
|
Camillo Bruni
2016/01/05 10:26:59
Could you combine this part with the parsing step
| |
| 2287 } | |
| 2288 | |
| 2289 | |
| 2290 // ES6 section 20.3.4.36 Date.prototype.toISOString ( ) | |
| 2291 BUILTIN(DatePrototypeToISOString) { | |
| 2292 HandleScope scope(isolate); | |
| 2293 CHECK_RECEIVER(JSDate, date, "Date.prototype.toISOString"); | |
| 2294 double const tv = date->value()->Number(); | |
| 2295 if (std::isnan(tv)) { | |
|
Camillo Bruni
2016/01/05 10:26:59
shouldn't +/-INF also be covered here? AFAIK std:i
Benedikt Meurer
2016/01/05 10:30:59
JSDate values can only be NaN or in the valid date
| |
| 2296 THROW_NEW_ERROR_RETURN_FAILURE( | |
| 2297 isolate, NewRangeError(MessageTemplate::kInvalidTimeValue)); | |
| 2298 } | |
| 2299 int64_t const time_ms = static_cast<int64_t>(tv); | |
| 2300 int year, month, day, weekday, hour, min, sec, ms; | |
| 2301 isolate->date_cache()->BreakDown(time_ms, &year, &month, &day, &weekday, | |
| 2302 &hour, &min, &sec, &ms); | |
| 2303 char buffer[128]; | |
| 2304 Vector<char> str(buffer, arraysize(buffer)); | |
| 2305 if (year >= 0 && year <= 9999) { | |
| 2306 SNPrintF(str, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", year, month + 1, day, | |
| 2307 hour, min, sec, ms); | |
| 2308 } else if (year < 0) { | |
| 2309 SNPrintF(str, "-%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", -year, month + 1, day, | |
| 2310 hour, min, sec, ms); | |
| 2311 } else { | |
| 2312 SNPrintF(str, "+%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", year, month + 1, day, | |
| 2313 hour, min, sec, ms); | |
| 2314 } | |
| 2315 return *isolate->factory()->NewStringFromAsciiChecked(str.start()); | |
| 2316 } | |
| 2317 | |
| 2318 | |
| 2319 // ES6 section 20.3.4.44 Date.prototype.valueOf ( ) | |
| 2320 BUILTIN(DatePrototypeValueOf) { | |
| 2321 HandleScope scope(isolate); | |
| 2322 CHECK_RECEIVER(JSDate, date, "Date.prototype.valueOf"); | |
| 2323 return date->value(); | |
| 2324 } | |
| 2325 | |
| 2326 | |
| 1941 // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ] ( hint ) | 2327 // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ] ( hint ) |
| 1942 BUILTIN(DateToPrimitive) { | 2328 BUILTIN(DatePrototypeToPrimitive) { |
| 1943 HandleScope scope(isolate); | 2329 HandleScope scope(isolate); |
| 1944 DCHECK_EQ(2, args.length()); | 2330 DCHECK_EQ(2, args.length()); |
| 1945 if (!args.receiver()->IsJSReceiver()) { | 2331 CHECK_RECEIVER(JSReceiver, receiver, "Date.prototype [ @@toPrimitive ]"); |
| 1946 THROW_NEW_ERROR_RETURN_FAILURE( | |
| 1947 isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, | |
| 1948 isolate->factory()->NewStringFromAsciiChecked( | |
| 1949 "Date.prototype [ @@toPrimitive ]"), | |
| 1950 args.receiver())); | |
| 1951 } | |
| 1952 Handle<JSReceiver> receiver = args.at<JSReceiver>(0); | |
| 1953 Handle<Object> hint = args.at<Object>(1); | 2332 Handle<Object> hint = args.at<Object>(1); |
| 1954 Handle<Object> result; | 2333 Handle<Object> result; |
| 1955 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 2334 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 1956 JSDate::ToPrimitive(receiver, hint)); | 2335 JSDate::ToPrimitive(receiver, hint)); |
| 1957 return *result; | 2336 return *result; |
| 1958 } | 2337 } |
| 1959 | 2338 |
| 1960 | 2339 |
| 1961 namespace { | 2340 namespace { |
| 1962 | 2341 |
| (...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2915 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 3294 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
| 2916 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 3295 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 2917 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 3296 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
| 2918 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 3297 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 2919 #undef DEFINE_BUILTIN_ACCESSOR_C | 3298 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 2920 #undef DEFINE_BUILTIN_ACCESSOR_A | 3299 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 2921 | 3300 |
| 2922 | 3301 |
| 2923 } // namespace internal | 3302 } // namespace internal |
| 2924 } // namespace v8 | 3303 } // namespace v8 |
| OLD | NEW |