Rewrite MakeDay function from JS to C++.
Review URL: http://codereview.chromium.org/661366 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3997 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
bfe1f02c3f
commit
b021997f81
@ -113,8 +113,13 @@ function EquivalentTime(t) {
|
|||||||
// we must do this, but for compatibility with other browsers, we use
|
// we must do this, but for compatibility with other browsers, we use
|
||||||
// the actual year if it is in the range 1970..2037
|
// the actual year if it is in the range 1970..2037
|
||||||
if (t >= 0 && t <= 2.1e12) return t;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -257,14 +262,6 @@ function TimeInYear(year) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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();
|
var four_year_cycle_table = CalculateDateTable();
|
||||||
|
|
||||||
|
|
||||||
@ -359,20 +356,18 @@ function FromJulianDay(julian) {
|
|||||||
function MakeDay(year, month, date) {
|
function MakeDay(year, month, date) {
|
||||||
if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return $NaN;
|
if (!$isFinite(year) || !$isFinite(month) || !$isFinite(date)) return $NaN;
|
||||||
|
|
||||||
// Conversion to integers.
|
|
||||||
year = TO_INTEGER(year);
|
year = TO_INTEGER(year);
|
||||||
month = TO_INTEGER(month);
|
month = TO_INTEGER(month);
|
||||||
date = TO_INTEGER(date);
|
date = TO_INTEGER(date);
|
||||||
|
|
||||||
// Overflow months into year.
|
if (year < kMinYear || year > kMaxYear ||
|
||||||
year = year + FLOOR(month/12);
|
month < kMinMonth || month > kMaxMonth ||
|
||||||
month = month % 12;
|
date < kMinDate || date > kMaxDate) {
|
||||||
if (month < 0) {
|
return $NaN;
|
||||||
month += 12;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return days relative to Jan 1 1970.
|
// Now we rely on year, month and date being SMIs.
|
||||||
return ToJulianDay(year, month, date) - kDayZeroInJulianDay;
|
return %DateMakeDay(year, month, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +73,16 @@ const kDayMask = 0x01f;
|
|||||||
const kYearShift = 9;
|
const kYearShift = 9;
|
||||||
const kMonthShift = 5;
|
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.
|
# Type query macros.
|
||||||
#
|
#
|
||||||
# Note: We have special support for typeof(foo) === 'bar' in the compiler.
|
# Note: We have special support for typeof(foo) === 'bar' in the compiler.
|
||||||
|
@ -4941,6 +4941,39 @@ static Object* Runtime_Math_tan(Arguments args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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) {
|
static Object* Runtime_NewArgumentsFast(Arguments args) {
|
||||||
NoHandleAllocation ha;
|
NoHandleAllocation ha;
|
||||||
ASSERT(args.length() == 3);
|
ASSERT(args.length() == 3);
|
||||||
|
@ -202,6 +202,7 @@ namespace internal {
|
|||||||
F(DateLocalTimezone, 1, 1) \
|
F(DateLocalTimezone, 1, 1) \
|
||||||
F(DateLocalTimeOffset, 0, 1) \
|
F(DateLocalTimeOffset, 0, 1) \
|
||||||
F(DateDaylightSavingsOffset, 1, 1) \
|
F(DateDaylightSavingsOffset, 1, 1) \
|
||||||
|
F(DateMakeDay, 3, 1) \
|
||||||
\
|
\
|
||||||
/* Numbers */ \
|
/* Numbers */ \
|
||||||
F(NumberIsFinite, 1, 1) \
|
F(NumberIsFinite, 1, 1) \
|
||||||
|
Loading…
Reference in New Issue
Block a user