зеркало из https://github.com/mozilla/gecko-dev.git
Bug 285615 - Define and implement JS_ClearDateCaches() API. r=waldo
This commit is contained in:
Родитель
600244941a
Коммит
5cc219c7d2
|
@ -6409,6 +6409,14 @@ JS_ObjectIsDate(JSContext *cx, JSObject *obj)
|
|||
return obj->isDate();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ClearDateCaches(JSContext *cx)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
js_ClearDateCaches();
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -5728,6 +5728,13 @@ JS_NewDateObjectMsec(JSContext *cx, double msec);
|
|||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_ObjectIsDate(JSContext *cx, JSObject *obj);
|
||||
|
||||
/*
|
||||
* Clears the cache of calculated local time from each Date object.
|
||||
* Call to propagate a system timezone change.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ClearDateCaches(JSContext *cx);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -128,6 +128,14 @@ using namespace js::types;
|
|||
* general going-over.
|
||||
*/
|
||||
|
||||
/* Constants defined by ES5 15.9.1.10. */
|
||||
const double HoursPerDay = 24.0;
|
||||
const double MinutesPerHour = 60;
|
||||
const double SecondsPerMinute = 60;
|
||||
const double msPerSecond = 1000;
|
||||
const double msPerMinute = msPerSecond * SecondsPerMinute;
|
||||
const double msPerHour = msPerMinute * MinutesPerHour;
|
||||
|
||||
/* ES5 15.9.1.2. */
|
||||
const double msPerDay = 86400000;
|
||||
|
||||
|
@ -310,8 +318,14 @@ WeekDay(double t)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* ES5 15.9.1.7. */
|
||||
static double LocalTZA; // set by js_InitDateClass
|
||||
/* ES5 15.9.1.7. Set by UpdateLocalTZA(). */
|
||||
static double LocalTZA;
|
||||
|
||||
inline void
|
||||
UpdateLocalTZA()
|
||||
{
|
||||
LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
|
||||
}
|
||||
|
||||
inline int
|
||||
DayFromMonth(int month, bool isLeapYear)
|
||||
|
@ -450,13 +464,6 @@ UTC(double t, JSContext *cx)
|
|||
}
|
||||
|
||||
/* ES5 15.9.1.10. */
|
||||
const double HoursPerDay = 24.0;
|
||||
const double MinutesPerHour = 60;
|
||||
const double SecondsPerMinute = 60;
|
||||
const double msPerSecond = 1000;
|
||||
const double msPerMinute = msPerSecond * SecondsPerMinute;
|
||||
const double msPerHour = msPerMinute * MinutesPerHour;
|
||||
|
||||
static double
|
||||
HourFromTime(double t)
|
||||
{
|
||||
|
@ -1288,10 +1295,20 @@ SetDateToNaN(JSContext *cx, JSObject *obj, Value *vp = NULL)
|
|||
* slots will be set to the UTC time without conversion.
|
||||
*/
|
||||
static bool
|
||||
FillLocalTimes(JSContext *cx, JSObject *obj)
|
||||
CacheLocalTime(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->isDate());
|
||||
|
||||
/* Check if the cache is already populated. */
|
||||
if (!obj->getSlot(JSObject::JSSLOT_DATE_LOCAL_TIME).isUndefined() &&
|
||||
obj->getSlot(JSObject::JSSLOT_DATE_TZA).toDouble() == LocalTZA)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Remember timezone used to generate the local cache. */
|
||||
obj->setSlot(JSObject::JSSLOT_DATE_TZA, DoubleValue(LocalTZA));
|
||||
|
||||
double utcTime = obj->getDateUTCTime().toNumber();
|
||||
|
||||
if (!MOZ_DOUBLE_IS_FINITE(utcTime)) {
|
||||
|
@ -1400,42 +1417,24 @@ FillLocalTimes(JSContext *cx, JSObject *obj)
|
|||
obj->setSlot(JSObject::JSSLOT_DATE_LOCAL_DATE, Int32Value(day - step));
|
||||
|
||||
int weekday = WeekDay(localTime);
|
||||
|
||||
obj->setSlot(JSObject::JSSLOT_DATE_LOCAL_DAY, Int32Value(weekday));
|
||||
|
||||
int seconds = yearSeconds % 60;
|
||||
|
||||
obj->setSlot(JSObject::JSSLOT_DATE_LOCAL_SECONDS, Int32Value(seconds));
|
||||
|
||||
int minutes = (yearSeconds / 60) % 60;
|
||||
|
||||
obj->setSlot(JSObject::JSSLOT_DATE_LOCAL_MINUTES, Int32Value(minutes));
|
||||
|
||||
int hours = (yearSeconds / (60 * 60)) % 24;
|
||||
|
||||
obj->setSlot(JSObject::JSSLOT_DATE_LOCAL_HOURS, Int32Value(hours));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Cache the local times in obj, if necessary. */
|
||||
static inline bool
|
||||
GetAndCacheLocalTime(JSContext *cx, JSObject *obj)
|
||||
inline bool
|
||||
GetCachedLocalTime(JSContext *cx, JSObject *obj, double *time)
|
||||
{
|
||||
JS_ASSERT(obj->isDate());
|
||||
|
||||
/* If the local time is undefined, we need to fill in the cached values. */
|
||||
if (obj->getSlot(JSObject::JSSLOT_DATE_LOCAL_TIME).isUndefined()) {
|
||||
if (!FillLocalTimes(cx, obj))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
GetAndCacheLocalTime(JSContext *cx, JSObject *obj, double *time)
|
||||
{
|
||||
if (!obj || !GetAndCacheLocalTime(cx, obj))
|
||||
if (!obj || !CacheLocalTime(cx, obj))
|
||||
return false;
|
||||
|
||||
*time = obj->getSlot(JSObject::JSSLOT_DATE_LOCAL_TIME).toDouble();
|
||||
|
@ -1471,7 +1470,7 @@ date_getYear(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, thisObj))
|
||||
if (!CacheLocalTime(cx, thisObj))
|
||||
return false;
|
||||
|
||||
Value yearVal = thisObj->getSlot(JSObject::JSSLOT_DATE_LOCAL_YEAR);
|
||||
|
@ -1497,7 +1496,7 @@ date_getFullYear(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, thisObj))
|
||||
if (!CacheLocalTime(cx, thisObj))
|
||||
return false;
|
||||
|
||||
args.rval() = thisObj->getSlot(JSObject::JSSLOT_DATE_LOCAL_YEAR);
|
||||
|
@ -1534,7 +1533,7 @@ date_getMonth(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, thisObj))
|
||||
if (!CacheLocalTime(cx, thisObj))
|
||||
return false;
|
||||
|
||||
args.rval() = thisObj->getSlot(JSObject::JSSLOT_DATE_LOCAL_MONTH);
|
||||
|
@ -1568,7 +1567,7 @@ date_getDate(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, thisObj))
|
||||
if (!CacheLocalTime(cx, thisObj))
|
||||
return false;
|
||||
|
||||
args.rval() = thisObj->getSlot(JSObject::JSSLOT_DATE_LOCAL_DATE);
|
||||
|
@ -1605,7 +1604,7 @@ date_getDay(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, thisObj))
|
||||
if (!CacheLocalTime(cx, thisObj))
|
||||
return false;
|
||||
|
||||
args.rval() = thisObj->getSlot(JSObject::JSSLOT_DATE_LOCAL_DAY);
|
||||
|
@ -1642,7 +1641,7 @@ date_getHours(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, thisObj))
|
||||
if (!CacheLocalTime(cx, thisObj))
|
||||
return false;
|
||||
|
||||
args.rval() = thisObj->getSlot(JSObject::JSSLOT_DATE_LOCAL_HOURS);
|
||||
|
@ -1679,7 +1678,7 @@ date_getMinutes(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, thisObj))
|
||||
if (!CacheLocalTime(cx, thisObj))
|
||||
return false;
|
||||
|
||||
args.rval() = thisObj->getSlot(JSObject::JSSLOT_DATE_LOCAL_MINUTES);
|
||||
|
@ -1718,7 +1717,7 @@ date_getUTCSeconds(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, thisObj))
|
||||
if (!CacheLocalTime(cx, thisObj))
|
||||
return false;
|
||||
|
||||
args.rval() = thisObj->getSlot(JSObject::JSSLOT_DATE_LOCAL_SECONDS);
|
||||
|
@ -1760,7 +1759,7 @@ date_getTimezoneOffset(JSContext *cx, unsigned argc, Value *vp)
|
|||
double utctime = thisObj->getDateUTCTime().toNumber();
|
||||
|
||||
double localtime;
|
||||
if (!GetAndCacheLocalTime(cx, thisObj, &localtime))
|
||||
if (!GetCachedLocalTime(cx, thisObj, &localtime))
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
@ -3069,8 +3068,7 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
|
|||
{
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
/* Set the static LocalTZA. */
|
||||
LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
|
||||
UpdateLocalTZA();
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &obj->asGlobal());
|
||||
|
||||
|
@ -3136,6 +3134,12 @@ js_NewDateObject(JSContext* cx, int year, int mon, int mday,
|
|||
return obj;
|
||||
}
|
||||
|
||||
void
|
||||
js_ClearDateCaches()
|
||||
{
|
||||
UpdateLocalTZA();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_DateIsValid(JSContext *cx, JSObject* obj)
|
||||
{
|
||||
|
@ -3148,7 +3152,7 @@ js_DateGetYear(JSContext *cx, JSObject* obj)
|
|||
double localtime;
|
||||
|
||||
/* Preserve legacy API behavior of returning 0 for invalid dates. */
|
||||
if (!GetAndCacheLocalTime(cx, obj, &localtime) || MOZ_DOUBLE_IS_NaN(localtime))
|
||||
if (!GetCachedLocalTime(cx, obj, &localtime) || MOZ_DOUBLE_IS_NaN(localtime))
|
||||
return 0;
|
||||
|
||||
return (int) YearFromTime(localtime);
|
||||
|
@ -3159,7 +3163,7 @@ js_DateGetMonth(JSContext *cx, JSObject* obj)
|
|||
{
|
||||
double localtime;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, obj, &localtime) || MOZ_DOUBLE_IS_NaN(localtime))
|
||||
if (!GetCachedLocalTime(cx, obj, &localtime) || MOZ_DOUBLE_IS_NaN(localtime))
|
||||
return 0;
|
||||
|
||||
return (int) MonthFromTime(localtime);
|
||||
|
@ -3170,7 +3174,7 @@ js_DateGetDate(JSContext *cx, JSObject* obj)
|
|||
{
|
||||
double localtime;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, obj, &localtime) || MOZ_DOUBLE_IS_NaN(localtime))
|
||||
if (!GetCachedLocalTime(cx, obj, &localtime) || MOZ_DOUBLE_IS_NaN(localtime))
|
||||
return 0;
|
||||
|
||||
return (int) DateFromTime(localtime);
|
||||
|
@ -3181,7 +3185,7 @@ js_DateGetHours(JSContext *cx, JSObject* obj)
|
|||
{
|
||||
double localtime;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, obj, &localtime) || MOZ_DOUBLE_IS_NaN(localtime))
|
||||
if (!GetCachedLocalTime(cx, obj, &localtime) || MOZ_DOUBLE_IS_NaN(localtime))
|
||||
return 0;
|
||||
|
||||
return (int) HourFromTime(localtime);
|
||||
|
@ -3192,7 +3196,7 @@ js_DateGetMinutes(JSContext *cx, JSObject* obj)
|
|||
{
|
||||
double localtime;
|
||||
|
||||
if (!GetAndCacheLocalTime(cx, obj, &localtime) || MOZ_DOUBLE_IS_NaN(localtime))
|
||||
if (!GetCachedLocalTime(cx, obj, &localtime) || MOZ_DOUBLE_IS_NaN(localtime))
|
||||
return 0;
|
||||
|
||||
return (int) MinFromTime(localtime);
|
||||
|
|
|
@ -65,6 +65,9 @@ extern JS_FRIEND_API(JSObject*)
|
|||
js_NewDateObject(JSContext* cx, int year, int mon, int mday,
|
||||
int hour, int min, int sec);
|
||||
|
||||
extern void
|
||||
js_ClearDateCaches();
|
||||
|
||||
extern JS_FRIEND_API(int)
|
||||
js_DateGetYear(JSContext *cx, JSObject* obj);
|
||||
|
||||
|
|
|
@ -616,24 +616,25 @@ struct JSObject : public js::ObjectImpl
|
|||
*/
|
||||
|
||||
static const uint32_t JSSLOT_DATE_UTC_TIME = 0;
|
||||
static const uint32_t JSSLOT_DATE_TZA = 1;
|
||||
|
||||
/*
|
||||
* Cached slots holding local properties of the date.
|
||||
* These are undefined until the first actual lookup occurs
|
||||
* and are reset to undefined whenever the date's time is modified.
|
||||
*/
|
||||
static const uint32_t JSSLOT_DATE_COMPONENTS_START = 1;
|
||||
static const uint32_t JSSLOT_DATE_COMPONENTS_START = 2;
|
||||
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_TIME = 1;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_YEAR = 2;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_MONTH = 3;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_DATE = 4;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_DAY = 5;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_HOURS = 6;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_MINUTES = 7;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_SECONDS = 8;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_TIME = JSSLOT_DATE_COMPONENTS_START + 0;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_YEAR = JSSLOT_DATE_COMPONENTS_START + 1;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_MONTH = JSSLOT_DATE_COMPONENTS_START + 2;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_DATE = JSSLOT_DATE_COMPONENTS_START + 3;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_DAY = JSSLOT_DATE_COMPONENTS_START + 4;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_HOURS = JSSLOT_DATE_COMPONENTS_START + 5;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_MINUTES = JSSLOT_DATE_COMPONENTS_START + 6;
|
||||
static const uint32_t JSSLOT_DATE_LOCAL_SECONDS = JSSLOT_DATE_COMPONENTS_START + 7;
|
||||
|
||||
static const uint32_t DATE_CLASS_RESERVED_SLOTS = 9;
|
||||
static const uint32_t DATE_CLASS_RESERVED_SLOTS = JSSLOT_DATE_LOCAL_SECONDS + 1;
|
||||
|
||||
inline const js::Value &getDateUTCTime() const;
|
||||
inline void setDateUTCTime(const js::Value &pthis);
|
||||
|
|
Загрузка…
Ссылка в новой задаче