| Index: runtime/lib/date.cc
|
| diff --git a/runtime/lib/date.cc b/runtime/lib/date.cc
|
| index 0c49e5b3fa0557e2e4d7d7e8d8d3891770cd54bb..bd28ee419eb32cd0ddad459c743e8efb93d94cb7 100644
|
| --- a/runtime/lib/date.cc
|
| +++ b/runtime/lib/date.cc
|
| @@ -13,140 +13,17 @@
|
|
|
| namespace dart {
|
|
|
| -typedef struct BrokenDownDate {
|
| - intptr_t year;
|
| - intptr_t month; // [1..12]
|
| - intptr_t day; // [1..31]
|
| - intptr_t hours;
|
| - intptr_t minutes;
|
| - intptr_t seconds;
|
| -} BrokenDownDate;
|
| -
|
| -
|
| -// Takes the seconds since epoch (midnight, January 1, 1970 UTC) and breaks it
|
| -// down into date and time.
|
| -// If 'dart_is_utc', then the broken down date and time are in the UTC timezone,
|
| -// otherwise the local timezone is used.
|
| -// The returned year is offset by 1900. The returned month is 0-based.
|
| -// Returns true if the conversion succeeds, false otherwise.
|
| -static bool BreakDownSecondsSinceEpoch(const Integer& dart_seconds,
|
| - const Bool& dart_is_utc,
|
| - BrokenDownDate* result) {
|
| - // Always fill the result to avoid unitialized use warnings.
|
| - result->year = 0;
|
| - result->month = 0;
|
| - result->day = 0;
|
| - result->hours = 0;
|
| - result->minutes = 0;
|
| - result->seconds = 0;
|
| -
|
| - bool is_utc = dart_is_utc.value();
|
| - int64_t seconds = dart_seconds.AsInt64Value();
|
| -
|
| - struct tm tm_result;
|
| - bool succeeded;
|
| - if (is_utc) {
|
| - succeeded = OS::GmTime(seconds, &tm_result);
|
| - } else {
|
| - succeeded = OS::LocalTime(seconds, &tm_result);
|
| - }
|
| - if (succeeded) {
|
| - result->year = tm_result.tm_year;
|
| - // C uses years since 1900, and not full years.
|
| - // Adding 1900 could overflow the intptr_t.
|
| - if (result->year > kIntptrMax - 1900) return false;
|
| - result->year += 1900;
|
| - // Dart has 1-based months (contrary to C's 0-based).
|
| - result->month= tm_result.tm_mon + 1;
|
| - result->day = tm_result.tm_mday;
|
| - result->hours = tm_result.tm_hour;
|
| - result->minutes = tm_result.tm_min;
|
| - result->seconds = tm_result.tm_sec;
|
| - }
|
| - return succeeded;
|
| -}
|
| -
|
| -
|
| -static bool BrokenDownToSecondsSinceEpoch(const BrokenDownDate& broken_down,
|
| - bool in_utc,
|
| - int64_t* result) {
|
| - // Always set the result to avoid unitialized use warnings.
|
| - *result = 0;
|
| -
|
| - struct tm tm_broken_down;
|
| - intptr_t year = broken_down.year;
|
| - // C works with years since 1900.
|
| - // Removing 1900 could underflow the intptr_t.
|
| - if (year < kIntptrMin + 1900) return false;
|
| - year -= 1900;
|
| - intptr_t month = broken_down.month;
|
| - // C works with 0-based months.
|
| - // Avoid underflows (even though they should not matter since the date would
|
| - // be invalid anyways.
|
| - if (month < 0) return false;
|
| - month--;
|
| - tm_broken_down.tm_year = static_cast<int>(year);
|
| - tm_broken_down.tm_mon = static_cast<int>(month);
|
| - tm_broken_down.tm_mday = static_cast<int>(broken_down.day);
|
| - tm_broken_down.tm_hour = static_cast<int>(broken_down.hours);
|
| - tm_broken_down.tm_min = static_cast<int>(broken_down.minutes);
|
| - tm_broken_down.tm_sec = static_cast<int>(broken_down.seconds);
|
| - // Verify that casting to int did not change the value.
|
| - if (tm_broken_down.tm_year != year
|
| - || tm_broken_down.tm_mon != month
|
| - || tm_broken_down.tm_mday != broken_down.day
|
| - || tm_broken_down.tm_hour != broken_down.hours
|
| - || tm_broken_down.tm_min != broken_down.minutes
|
| - || tm_broken_down.tm_sec != broken_down.seconds) {
|
| - return false;
|
| - }
|
| - if (in_utc) {
|
| - return OS::MkGmTime(&tm_broken_down, result);
|
| - } else {
|
| - return OS::MkTime(&tm_broken_down, result);
|
| - }
|
| -}
|
| -
|
| -
|
| -DEFINE_NATIVE_ENTRY(DateNatives_brokenDownToSecondsSinceEpoch, 7) {
|
| - GET_NATIVE_ARGUMENT(Integer, dart_years, arguments->At(0));
|
| - GET_NATIVE_ARGUMENT(Smi, dart_month, arguments->At(1));
|
| - GET_NATIVE_ARGUMENT(Smi, dart_day, arguments->At(2));
|
| - GET_NATIVE_ARGUMENT(Smi, dart_hours, arguments->At(3));
|
| - GET_NATIVE_ARGUMENT(Smi, dart_minutes, arguments->At(4));
|
| - GET_NATIVE_ARGUMENT(Smi, dart_seconds, arguments->At(5));
|
| - GET_NATIVE_ARGUMENT(Bool, dart_is_utc, arguments->At(6));
|
| - if (!dart_years.IsSmi()) {
|
| - UNIMPLEMENTED();
|
| - }
|
| - Smi& smi_years = Smi::Handle();
|
| - smi_years ^= dart_years.raw();
|
| - BrokenDownDate broken_down;
|
| - broken_down.year = smi_years.Value();
|
| - broken_down.month = dart_month.Value();
|
| - broken_down.day = dart_day.Value();
|
| - broken_down.hours = dart_hours.Value();
|
| - broken_down.minutes = dart_minutes.Value();
|
| - broken_down.seconds = dart_seconds.Value();
|
| - int64_t value;
|
| - bool succeeded = BrokenDownToSecondsSinceEpoch(broken_down,
|
| - dart_is_utc.value(),
|
| - &value);
|
| - if (!succeeded) {
|
| - UNIMPLEMENTED();
|
| - }
|
| - arguments->SetReturn(Integer::Handle(Integer::New(value)));
|
| -}
|
| -
|
| +static int32_t kMaxAllowedSeconds = 2100000000;
|
|
|
| DEFINE_NATIVE_ENTRY(DateNatives_timeZoneName, 1) {
|
| GET_NATIVE_ARGUMENT(Integer, dart_seconds, arguments->At(0));
|
| int64_t seconds = dart_seconds.AsInt64Value();
|
| - const char* name;
|
| - bool succeeded = OS::GetTimeZoneName(seconds, &name);
|
| - if (!succeeded) {
|
| - UNIMPLEMENTED();
|
| + if (seconds < 0 || seconds > kMaxAllowedSeconds) {
|
| + GrowableArray<const Object*> args;
|
| + args.Add(&dart_seconds);
|
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
|
| }
|
| + const char* name = OS::GetTimeZoneName(seconds);
|
| const String& dart_name = String::Handle(String::New(name));
|
| arguments->SetReturn(dart_name);
|
| }
|
| @@ -155,104 +32,28 @@ DEFINE_NATIVE_ENTRY(DateNatives_timeZoneName, 1) {
|
| DEFINE_NATIVE_ENTRY(DateNatives_timeZoneOffsetInSeconds, 1) {
|
| GET_NATIVE_ARGUMENT(Integer, dart_seconds, arguments->At(0));
|
| int64_t seconds = dart_seconds.AsInt64Value();
|
| - int offset;
|
| - bool succeeded = OS::GetTimeZoneOffsetInSeconds(seconds, &offset);
|
| - if (!succeeded) {
|
| - UNIMPLEMENTED();
|
| + if (seconds < 0 || seconds > kMaxAllowedSeconds) {
|
| + GrowableArray<const Object*> args;
|
| + args.Add(&dart_seconds);
|
| + Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
|
| }
|
| + int offset = OS::GetTimeZoneOffsetInSeconds(seconds);
|
| const Integer& dart_offset = Integer::Handle(Integer::New(offset));
|
| arguments->SetReturn(dart_offset);
|
| }
|
|
|
|
|
| +DEFINE_NATIVE_ENTRY(DateNatives_localTimeZoneAdjustmentInSeconds, 0) {
|
| + int adjustment = OS::GetLocalTimeZoneAdjustmentInSeconds();
|
| + const Integer& dart_adjustment = Integer::Handle(Integer::New(adjustment));
|
| + arguments->SetReturn(dart_adjustment);
|
| +}
|
| +
|
| +
|
| DEFINE_NATIVE_ENTRY(DateNatives_currentTimeMillis, 0) {
|
| const Integer& time = Integer::Handle(
|
| Integer::New(OS::GetCurrentTimeMillis()));
|
| arguments->SetReturn(time);
|
| }
|
|
|
| -
|
| -DEFINE_NATIVE_ENTRY(DateNatives_getYear, 2) {
|
| - GET_NATIVE_ARGUMENT(Integer, dart_seconds, arguments->At(0));
|
| - GET_NATIVE_ARGUMENT(Bool, dart_is_utc, arguments->At(1));
|
| - BrokenDownDate broken_down;
|
| - bool succeeded =
|
| - BreakDownSecondsSinceEpoch(dart_seconds, dart_is_utc, &broken_down);
|
| - if (!succeeded) {
|
| - UNIMPLEMENTED();
|
| - }
|
| - intptr_t year = broken_down.year;
|
| - arguments->SetReturn(Integer::Handle(Integer::New(year)));
|
| -}
|
| -
|
| -
|
| -DEFINE_NATIVE_ENTRY(DateNatives_getMonth, 2) {
|
| - GET_NATIVE_ARGUMENT(Integer, dart_seconds, arguments->At(0));
|
| - GET_NATIVE_ARGUMENT(Bool, dart_is_utc, arguments->At(1));
|
| - BrokenDownDate broken_down;
|
| - bool succeeded =
|
| - BreakDownSecondsSinceEpoch(dart_seconds, dart_is_utc, &broken_down);
|
| - if (!succeeded) {
|
| - UNIMPLEMENTED();
|
| - }
|
| - const Smi& result = Smi::Handle(Smi::New(broken_down.month));
|
| - arguments->SetReturn(result);
|
| -}
|
| -
|
| -
|
| -DEFINE_NATIVE_ENTRY(DateNatives_getDay, 2) {
|
| - GET_NATIVE_ARGUMENT(Integer, dart_seconds, arguments->At(0));
|
| - GET_NATIVE_ARGUMENT(Bool, dart_is_utc, arguments->At(1));
|
| - BrokenDownDate broken_down;
|
| - bool succeeded =
|
| - BreakDownSecondsSinceEpoch(dart_seconds, dart_is_utc, &broken_down);
|
| - if (!succeeded) {
|
| - UNIMPLEMENTED();
|
| - }
|
| - const Smi& result = Smi::Handle(Smi::New(broken_down.day));
|
| - arguments->SetReturn(result);
|
| -}
|
| -
|
| -
|
| -DEFINE_NATIVE_ENTRY(DateNatives_getHours, 2) {
|
| - GET_NATIVE_ARGUMENT(Integer, dart_seconds, arguments->At(0));
|
| - GET_NATIVE_ARGUMENT(Bool, dart_is_utc, arguments->At(1));
|
| - BrokenDownDate broken_down;
|
| - bool succeeded =
|
| - BreakDownSecondsSinceEpoch(dart_seconds, dart_is_utc, &broken_down);
|
| - if (!succeeded) {
|
| - UNIMPLEMENTED();
|
| - }
|
| - const Smi& result = Smi::Handle(Smi::New(broken_down.hours));
|
| - arguments->SetReturn(result);
|
| -}
|
| -
|
| -
|
| -DEFINE_NATIVE_ENTRY(DateNatives_getMinutes, 2) {
|
| - GET_NATIVE_ARGUMENT(Integer, dart_seconds, arguments->At(0));
|
| - GET_NATIVE_ARGUMENT(Bool, dart_is_utc, arguments->At(1));
|
| - BrokenDownDate broken_down;
|
| - bool succeeded =
|
| - BreakDownSecondsSinceEpoch(dart_seconds, dart_is_utc, &broken_down);
|
| - if (!succeeded) {
|
| - UNIMPLEMENTED();
|
| - }
|
| - const Smi& result = Smi::Handle(Smi::New(broken_down.minutes));
|
| - arguments->SetReturn(result);
|
| -}
|
| -
|
| -
|
| -DEFINE_NATIVE_ENTRY(DateNatives_getSeconds, 2) {
|
| - GET_NATIVE_ARGUMENT(Integer, dart_seconds, arguments->At(0));
|
| - GET_NATIVE_ARGUMENT(Bool, dart_is_utc, arguments->At(1));
|
| - BrokenDownDate broken_down;
|
| - bool succeeded =
|
| - BreakDownSecondsSinceEpoch(dart_seconds, dart_is_utc, &broken_down);
|
| - if (!succeeded) {
|
| - UNIMPLEMENTED();
|
| - }
|
| - const Smi& result = Smi::Handle(Smi::New(broken_down.seconds));
|
| - arguments->SetReturn(result);
|
| -}
|
| -
|
| } // namespace dart
|
|
|