Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index bc0a82e6868ab16718f6c71451bf24e355134e61..ec5477ff804a65ac74deda77788de282dee27cb2 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" |
| @@ -1112,7 +1113,7 @@ void JSObject::JSObjectShortPrint(StringStream* accumulator) { |
| switch (map()->instance_type()) { |
| case JS_ARRAY_TYPE: { |
| double length = JSArray::cast(this)->length()->Number(); |
| - accumulator->Add("<JS array[%u]>", static_cast<uint32_t>(length)); |
| + accumulator->Add("<JS Array[%u]>", static_cast<uint32_t>(length)); |
| break; |
| } |
| case JS_WEAK_MAP_TYPE: { |
| @@ -1383,6 +1384,7 @@ void HeapObject::IterateBody(InstanceType type, int object_size, |
| case JS_OBJECT_TYPE: |
| case JS_CONTEXT_EXTENSION_OBJECT_TYPE: |
| case JS_VALUE_TYPE: |
| + case JS_DATE_TYPE: |
| case JS_ARRAY_TYPE: |
| case JS_SET_TYPE: |
| case JS_MAP_TYPE: |
| @@ -13175,4 +13177,134 @@ 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(); |
| + default: |
| + ASSERT(index == kSecond); |
|
rossberg
2012/03/06 15:55:50
I think in other places we tend to use a regular c
ulan
2012/03/07 10:55:21
Done.
|
| + return sec(); |
| + } |
| + } |
| + |
| + 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); |
| + int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days); |
| + |
| + if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000); |
|
rossberg
2012/03/06 15:55:50
Maybe consider using another 'switch' here for cla
ulan
2012/03/07 10:55:21
Moved the "days" case up, now only two cases are l
|
| + if (index == kDays) return Smi::FromInt(days); |
|
rossberg
2012/03/06 15:55:50
You could move this up before computing time_in_da
ulan
2012/03/07 10:55:21
Done.
|
| + 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); |
| + int days = DateCache::DaysFromTime(time_ms); |
|
rossberg
2012/03/06 15:55:50
You can move this after the kTimezoneOffset case.
ulan
2012/03/07 10:55:21
Done.
|
| + |
| + if (index == kTimezoneOffset) { |
| + int64_t time_ms = static_cast<int64_t>(value); |
| + return Smi::FromInt(date_cache->TimezoneOffset(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); |
|
rossberg
2012/03/06 15:55:50
Perhaps use a switch here.
ulan
2012/03/07 10:55:21
I am not sure, just three cases.
|
| + 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); |
| + default: |
| + ASSERT(index == kTimeInDayUTC); |
|
rossberg
2012/03/06 15:55:50
See above, consider using an unreachable default.
ulan
2012/03/07 10:55:21
Done.
|
| + return Smi::FromInt(time_in_day_ms); |
| + } |
| + |
| + 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, time_in_day_ms, year, month, day, weekday, hour, min, sec; |
|
rossberg
2012/03/06 15:55:50
Avoid uninitialized declarations if you can (like
ulan
2012/03/07 10:55:21
Done.
|
| + days = DateCache::DaysFromTime(local_time_ms); |
| + time_in_day_ms = DateCache::TimeInDay(local_time_ms, days); |
| + date_cache->YearMonthDayFromDays(days, &year, &month, &day); |
| + weekday = date_cache->Weekday(days); |
| + hour = time_in_day_ms / (60 * 60 * 1000); |
| + min = (time_in_day_ms / (60 * 1000)) % 60; |
| + 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 |