| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 9c03d2b8fa75a769c74788d2b35c0c17f8868405..7a46206eb12e14560cd286f28443cf78c05b5b80 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -33,6 +33,7 @@
|
| #include "codegen.h"
|
| #include "debug.h"
|
| #include "deoptimizer.h"
|
| +#include "date.h"
|
| #include "elements.h"
|
| #include "execution.h"
|
| #include "full-codegen.h"
|
| @@ -12970,4 +12971,133 @@ int BreakPointInfo::GetBreakPointCount() {
|
| #endif // ENABLE_DEBUGGER_SUPPORT
|
|
|
|
|
| +MaybeObject* JSDate::GetField(Object* object, Smi* index) {
|
| + return JSDate::cast(object)->DoGetField(
|
| + static_cast<FieldIndex>(index->value()));
|
| +}
|
| +
|
| +
|
| +Object* JSDate::DoGetField(FieldIndex index) {
|
| + ASSERT(index != kDateValue);
|
| +
|
| + DateCache* date_cache = GetIsolate()->date_cache();
|
| +
|
| + if (index < kFirstUncachedField) {
|
| + Object* stamp = cache_stamp();
|
| + if (stamp != date_cache->stamp() && stamp->IsSmi()) {
|
| + // Since the stamp is not NaN, the value is also not NaN.
|
| + int64_t local_time_ms =
|
| + static_cast<int64_t>(date_cache->ToLocal(value()->Number()));
|
| + SetLocalFields(local_time_ms, date_cache);
|
| + }
|
| + switch (index) {
|
| + case kYear: return year();
|
| + case kMonth: return month();
|
| + case kDay: return day();
|
| + case kWeekday: return weekday();
|
| + case kHour: return hour();
|
| + case kMinute: return min();
|
| + case kSecond: return sec();
|
| + default: UNREACHABLE();
|
| + }
|
| + }
|
| +
|
| + if (index >= kFirstUTCField) {
|
| + return GetUTCField(index, value()->Number(), date_cache);
|
| + }
|
| +
|
| + double time = value()->Number();
|
| + if (isnan(time)) return GetIsolate()->heap()->nan_value();
|
| +
|
| + int64_t local_time_ms = static_cast<int64_t>(date_cache->ToLocal(time));
|
| + int days = DateCache::DaysFromTime(local_time_ms);
|
| +
|
| + if (index == kDays) return Smi::FromInt(days);
|
| +
|
| + int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
|
| + if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000);
|
| + ASSERT(index == kTimeInDay);
|
| + return Smi::FromInt(time_in_day_ms);
|
| +}
|
| +
|
| +
|
| +Object* JSDate::GetUTCField(FieldIndex index,
|
| + double value,
|
| + DateCache* date_cache) {
|
| + ASSERT(index >= kFirstUTCField);
|
| +
|
| + if (isnan(value)) return GetIsolate()->heap()->nan_value();
|
| +
|
| + int64_t time_ms = static_cast<int64_t>(value);
|
| +
|
| + if (index == kTimezoneOffset) {
|
| + return Smi::FromInt(date_cache->TimezoneOffset(time_ms));
|
| + }
|
| +
|
| + int days = DateCache::DaysFromTime(time_ms);
|
| +
|
| + if (index == kWeekdayUTC) return Smi::FromInt(date_cache->Weekday(days));
|
| +
|
| + if (index <= kDayUTC) {
|
| + int year, month, day;
|
| + date_cache->YearMonthDayFromDays(days, &year, &month, &day);
|
| + if (index == kYearUTC) return Smi::FromInt(year);
|
| + if (index == kMonthUTC) return Smi::FromInt(month);
|
| + ASSERT(index == kDayUTC);
|
| + return Smi::FromInt(day);
|
| + }
|
| +
|
| + int time_in_day_ms = DateCache::TimeInDay(time_ms, days);
|
| + switch (index) {
|
| + case kHourUTC: return Smi::FromInt(time_in_day_ms / (60 * 60 * 1000));
|
| + case kMinuteUTC: return Smi::FromInt((time_in_day_ms / (60 * 1000)) % 60);
|
| + case kSecondUTC: return Smi::FromInt((time_in_day_ms / 1000) % 60);
|
| + case kMillisecondUTC: return Smi::FromInt(time_in_day_ms % 1000);
|
| + case kDaysUTC: return Smi::FromInt(days);
|
| + case kTimeInDayUTC: return Smi::FromInt(time_in_day_ms);
|
| + default: UNREACHABLE();
|
| + }
|
| +
|
| + UNREACHABLE();
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +void JSDate::SetValue(Object* value, bool is_value_nan) {
|
| + set_value(value);
|
| + if (is_value_nan) {
|
| + HeapNumber* nan = GetIsolate()->heap()->nan_value();
|
| + set_cache_stamp(nan, SKIP_WRITE_BARRIER);
|
| + set_year(nan, SKIP_WRITE_BARRIER);
|
| + set_month(nan, SKIP_WRITE_BARRIER);
|
| + set_day(nan, SKIP_WRITE_BARRIER);
|
| + set_hour(nan, SKIP_WRITE_BARRIER);
|
| + set_min(nan, SKIP_WRITE_BARRIER);
|
| + set_sec(nan, SKIP_WRITE_BARRIER);
|
| + set_weekday(nan, SKIP_WRITE_BARRIER);
|
| + } else {
|
| + set_cache_stamp(Smi::FromInt(DateCache::kInvalidStamp), SKIP_WRITE_BARRIER);
|
| + }
|
| +}
|
| +
|
| +
|
| +void JSDate::SetLocalFields(int64_t local_time_ms, DateCache* date_cache) {
|
| + int days = DateCache::DaysFromTime(local_time_ms);
|
| + int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
|
| + int year, month, day;
|
| + date_cache->YearMonthDayFromDays(days, &year, &month, &day);
|
| + int weekday = date_cache->Weekday(days);
|
| + int hour = time_in_day_ms / (60 * 60 * 1000);
|
| + int min = (time_in_day_ms / (60 * 1000)) % 60;
|
| + int sec = (time_in_day_ms / 1000) % 60;
|
| + set_cache_stamp(date_cache->stamp());
|
| + set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
|
| + set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
|
| + set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
|
| + set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
|
| + set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
|
| + set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
|
| + set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
|
| +}
|
| +
|
| } } // namespace v8::internal
|
|
|