Revision: 3997
Author: o...@chromium.org
Date: Tue Mar 2 05:29:26 2010
Log: Rewrite MakeDay function from JS to C++.
Review URL: http://codereview.chromium.org/661366
http://code.google.com/p/v8/source/detail?r=3997
Modified:
/branches/bleeding_edge/src/date-delay.js
/branches/bleeding_edge/src/macros.py
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/runtime.h
=======================================
--- /branches/bleeding_edge/src/date-delay.js Thu Jan 14 00:55:15 2010
+++ /branches/bleeding_edge/src/date-delay.js Tue Mar 2 05:29:26 2010
@@ -113,8 +113,13 @@
// we must do this, but for compatibility with other browsers, we use
// the actual year if it is in the range 1970..2037
if (t >= 0 && t <= 2.1e12) return t;
- var day = MakeDay(EquivalentYear(YEAR_FROM_TIME(t)), MONTH_FROM_TIME(t),
DATE_FROM_TIME(t));
- return TimeClip(MakeDate(day, TimeWithinDay(t)));
+
+ // We call the function from runtime.cc directly to avoid extra checks
which
+ // are unneeded.
+ var day = %DateMakeDay(EquivalentYear(YEAR_FROM_TIME(t)),
+ MONTH_FROM_TIME(t),
+ DATE_FROM_TIME(t));
+ return MakeDate(day, TimeWithinDay(t));
}
@@ -256,14 +261,6 @@
return DaysInYear(year) * msPerDay;
}
-
-// Compute modified Julian day from year, month, date.
-function ToJulianDay(year, month, date) {
- var jy = (month > 1) ? year : year - 1;
- var jm = (month > 1) ? month + 2 : month + 14;
- var ja = FLOOR(jy / 100);
- return FLOOR(FLOOR(365.25*jy) + FLOOR(30.6001*jm) + date + 1720995) + 2
- ja + FLOOR(0.25*ja);
-}
var four_year_cycle_table = CalculateDateTable();
@@ -359,20 +356,18 @@
function MakeDay(year, month, date) {
if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return
$NaN;
- // Conversion to integers.
year = TO_INTEGER(year);
month = TO_INTEGER(month);
date = TO_INTEGER(date);
- // Overflow months into year.
- year = year + FLOOR(month/12);
- month = month % 12;
- if (month < 0) {
- month += 12;
+ if (year < kMinYear || year > kMaxYear ||
+ month < kMinMonth || month > kMaxMonth ||
+ date < kMinDate || date > kMaxDate) {
+ return $NaN;
}
- // Return days relative to Jan 1 1970.
- return ToJulianDay(year, month, date) - kDayZeroInJulianDay;
+ // Now we rely on year, month and date being SMIs.
+ return %DateMakeDay(year, month, date);
}
=======================================
--- /branches/bleeding_edge/src/macros.py Fri Feb 19 05:07:37 2010
+++ /branches/bleeding_edge/src/macros.py Tue Mar 2 05:29:26 2010
@@ -73,6 +73,16 @@
const kYearShift = 9;
const kMonthShift = 5;
+# Limits for parts of the date, so that we support all the dates that
+# ECMA 262 - 15.9.1.1 requires us to, but at the same time be sure that
+# the date (days since 1970) is in SMI range.
+const kMinYear = -1000000;
+const kMaxYear = 1000000;
+const kMinMonth = -10000000;
+const kMaxMonth = 10000000;
+const kMinDate = -100000000;
+const kMaxDate = 100000000;
+
# Type query macros.
#
# Note: We have special support for typeof(foo) === 'bar' in the compiler.
=======================================
--- /branches/bleeding_edge/src/runtime.cc Mon Mar 1 07:33:30 2010
+++ /branches/bleeding_edge/src/runtime.cc Tue Mar 2 05:29:26 2010
@@ -4939,6 +4939,39 @@
CONVERT_DOUBLE_CHECKED(x, args[0]);
return TranscendentalCache::Get(TranscendentalCache::TAN, x);
}
+
+
+static Object* Runtime_DateMakeDay(Arguments args) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 3);
+
+ CONVERT_SMI_CHECKED(year, args[0]);
+ CONVERT_SMI_CHECKED(month, args[1]);
+ CONVERT_SMI_CHECKED(date, args[2]);
+
+ static const int day_from_month[] = {0, 31, 59, 90, 120, 151,
+ 181, 212, 243, 273, 304, 334};
+ static const int day_from_month_leap[] = {0, 31, 60, 91, 121, 152,
+ 182, 213, 244, 274, 305, 335};
+
+ year += month / 12;
+ month %= 12;
+ if (month < 0) {
+ year--;
+ month += 12;
+ }
+
+ static const int base_day = 365*1969 + 1969/4 - 1969/100 + 1969/400;
+ int year1 = year - 1;
+ int day_from_year = 365 * year1 + year1 / 4 - year1 / 100 + year1 / 400 -
+ base_day;
+
+ if (year % 4 || (year % 100 == 0 && year % 400 != 0)) {
+ return Smi::FromInt(day_from_year + day_from_month[month] + date - 1);
+ } else {
+ return Smi::FromInt(day_from_year + day_from_month_leap[month] + date
- 1);
+ }
+}
static Object* Runtime_NewArgumentsFast(Arguments args) {
=======================================
--- /branches/bleeding_edge/src/runtime.h Mon Mar 1 07:33:30 2010
+++ /branches/bleeding_edge/src/runtime.h Tue Mar 2 05:29:26 2010
@@ -202,6 +202,7 @@
F(DateLocalTimezone, 1, 1) \
F(DateLocalTimeOffset, 0, 1) \
F(DateDaylightSavingsOffset, 1, 1) \
+ F(DateMakeDay, 3, 1) \
\
/* Numbers */ \
F(NumberIsFinite, 1, 1) \
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev