aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-04-23 10:16:04 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-02 14:19:58 +0000
commitd1047f4eba219e01fef6faf56dccd923fc0e3ce1 (patch)
treea1012db46bf64df2656f7505bc98d5c0f0325d4c
parent5c0dd5df5c8761c3317c41abdd201bd759fe1a1e (diff)
Remove static localTZA variable
This one leads to lots of complaints from thread sanitizers as we're writing to it from multiple threads. Move it into the engine to avoid the noise. Change-Id: I081eeb1de80e623c68fcbd17df1875943c6c019c Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp103
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine_p.h1
-rw-r--r--src/qml/qml/qqmllocale.cpp2
4 files changed, 54 insertions, 54 deletions
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index bc9b3013d1..394a7f3de3 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -89,9 +89,6 @@ static const double msPerMinute = 60000.0;
static const double msPerHour = 3600000.0;
static const double msPerDay = 86400000.0;
-// The current *standard* time offset, regardless of DST:
-static double LocalTZA = 0.0; // initialized at startup
-
static inline double TimeWithinDay(double t)
{
double r = ::fmod(t, msPerDay);
@@ -318,14 +315,14 @@ static inline double MakeDate(double day, double time)
against the ECMAScript spec is https://github.com/tc39/ecma262/issues/725
*/
-static inline double DaylightSavingTA(double t) // t is a UTC time
+static inline double DaylightSavingTA(double t, double localTZA) // t is a UTC time
{
return QTimeZone::systemTimeZone().offsetFromUtc(
- QDateTime::fromMSecsSinceEpoch(qint64(t), Qt::UTC)) * 1e3 - LocalTZA;
+ QDateTime::fromMSecsSinceEpoch(qint64(t), Qt::UTC)) * 1e3 - localTZA;
}
#else
// This implementation fails to take account of past changes in standard offset.
-static inline double DaylightSavingTA(double t)
+static inline double DaylightSavingTA(double t, double /*localTZA*/)
{
struct tm tmtm;
#if defined(Q_CC_MSVC)
@@ -348,19 +345,19 @@ static inline double DaylightSavingTA(double t)
}
#endif // USE_QTZ_SYSTEM_ZONE
-static inline double LocalTime(double t)
+static inline double LocalTime(double t, double localTZA)
{
// Flawed, yet verbatim from the spec:
- return t + LocalTZA + DaylightSavingTA(t);
+ return t + localTZA + DaylightSavingTA(t, localTZA);
}
// The spec does note [*] that UTC and LocalTime are not quite mutually inverse.
// [*] http://www.ecma-international.org/ecma-262/7.0/index.html#sec-utc-t
-static inline double UTC(double t)
+static inline double UTC(double t, double localTZA)
{
// Flawed, yet verbatim from the spec:
- return t - LocalTZA - DaylightSavingTA(t - LocalTZA);
+ return t - localTZA - DaylightSavingTA(t - localTZA, localTZA);
}
static inline double currentTime()
@@ -377,7 +374,7 @@ static inline double TimeClip(double t)
return Primitive::toInteger(t) + 0;
}
-static inline double ParseString(const QString &s)
+static inline double ParseString(const QString &s, double localTZA)
{
/*
First, try the format defined in ECMA 262's "Date Time String Format";
@@ -533,7 +530,7 @@ static inline double ParseString(const QString &s)
if (seenZ)
t -= offset * offsetSign * 60 * 1000;
else if (seenT) // No zone specified, treat date-time as local time
- t = UTC(t);
+ t = UTC(t, localTZA);
// else: treat plain date as already in UTC
return t;
}
@@ -621,12 +618,12 @@ static inline QDateTime ToDateTime(double t, Qt::TimeSpec spec)
return QDateTime::fromMSecsSinceEpoch(t, Qt::UTC).toTimeSpec(spec);
}
-static inline QString ToString(double t)
+static inline QString ToString(double t, double localTZA)
{
if (std::isnan(t))
return QStringLiteral("Invalid Date");
QString str = ToDateTime(t, Qt::LocalTime).toString() + QLatin1String(" GMT");
- double tzoffset = LocalTZA + DaylightSavingTA(t);
+ double tzoffset = localTZA + DaylightSavingTA(t, localTZA);
if (tzoffset) {
int hours = static_cast<int>(::fabs(tzoffset) / 1000 / 60 / 60);
int mins = int(::fabs(tzoffset) / 1000 / 60) % 60;
@@ -730,7 +727,7 @@ void Heap::DateObject::init(const QTime &time)
*/
static const double d = MakeDay(1925, 5, 8);
double t = MakeTime(time.hour(), time.minute(), time.second(), time.msec());
- date = TimeClip(UTC(MakeDate(d, t)));
+ date = TimeClip(UTC(MakeDate(d, t), internalClass->engine->localTZA));
}
QDateTime DateObject::toQDateTime() const
@@ -747,13 +744,14 @@ void Heap::DateCtor::init(QV4::ExecutionContext *scope)
ReturnedValue DateCtor::callAsConstructor(const FunctionObject *that, const Value *argv, int argc)
{
+ ExecutionEngine *e = that->engine();
double t = 0;
if (argc == 0)
t = currentTime();
else if (argc == 1) {
- Scope scope(that->engine());
+ Scope scope(e);
ScopedValue arg(scope, argv[0]);
if (DateObject *d = arg->as<DateObject>()) {
t = d->date();
@@ -761,7 +759,7 @@ ReturnedValue DateCtor::callAsConstructor(const FunctionObject *that, const Valu
arg = RuntimeHelpers::toPrimitive(arg, PREFERREDTYPE_HINT);
if (String *s = arg->stringValue())
- t = ParseString(s->toQString());
+ t = ParseString(s->toQString(), e->localTZA);
else
t = TimeClip(arg->toNumber());
}
@@ -778,16 +776,17 @@ ReturnedValue DateCtor::callAsConstructor(const FunctionObject *that, const Valu
if (year >= 0 && year <= 99)
year += 1900;
t = MakeDate(MakeDay(year, month, day), MakeTime(hours, mins, secs, ms));
- t = TimeClip(UTC(t));
+ t = TimeClip(UTC(t, e->localTZA));
}
- return Encode(that->engine()->newDateObject(Primitive::fromDouble(t)));
+ return Encode(e->newDateObject(Primitive::fromDouble(t)));
}
ReturnedValue DateCtor::call(const FunctionObject *m, const Value *, const Value *, int)
{
+ ExecutionEngine *e = m->engine();
double t = currentTime();
- return m->engine()->newString(ToString(t))->asReturnedValue();
+ return e->newString(ToString(t, e->localTZA))->asReturnedValue();
}
void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
@@ -796,7 +795,7 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
ScopedObject o(scope);
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(7));
- LocalTZA = getLocalTZA();
+ engine->localTZA = getLocalTZA();
ctor->defineDefaultProperty(QStringLiteral("parse"), method_parse, 1);
ctor->defineDefaultProperty(QStringLiteral("UTC"), method_UTC, 7);
@@ -872,12 +871,12 @@ double DatePrototype::getThisDate(ExecutionEngine *v4, const Value *thisObject)
return 0;
}
-ReturnedValue DatePrototype::method_parse(const FunctionObject *, const Value *, const Value *argv, int argc)
+ReturnedValue DatePrototype::method_parse(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
if (!argc)
return Encode(qt_qnan());
else
- return Encode(ParseString(argv[0].toQString()));
+ return Encode(ParseString(argv[0].toQString(), f->engine()->localTZA));
}
ReturnedValue DatePrototype::method_UTC(const FunctionObject *, const Value *, const Value *argv, int argc)
@@ -909,7 +908,7 @@ ReturnedValue DatePrototype::method_toString(const FunctionObject *b, const Valu
{
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
- return Encode(v4->newString(ToString(t)));
+ return Encode(v4->newString(ToString(t, v4->localTZA)));
}
ReturnedValue DatePrototype::method_toDateString(const FunctionObject *b, const Value *thisObject, const Value *, int)
@@ -966,7 +965,7 @@ ReturnedValue DatePrototype::method_getYear(const FunctionObject *b, const Value
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
- t = YearFromTime(LocalTime(t)) - 1900;
+ t = YearFromTime(LocalTime(t, v4->localTZA)) - 1900;
return Encode(t);
}
@@ -975,7 +974,7 @@ ReturnedValue DatePrototype::method_getFullYear(const FunctionObject *b, const V
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
- t = YearFromTime(LocalTime(t));
+ t = YearFromTime(LocalTime(t, v4->localTZA));
return Encode(t);
}
@@ -993,7 +992,7 @@ ReturnedValue DatePrototype::method_getMonth(const FunctionObject *b, const Valu
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
- t = MonthFromTime(LocalTime(t));
+ t = MonthFromTime(LocalTime(t, v4->localTZA));
return Encode(t);
}
@@ -1011,7 +1010,7 @@ ReturnedValue DatePrototype::method_getDate(const FunctionObject *b, const Value
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
- t = DateFromTime(LocalTime(t));
+ t = DateFromTime(LocalTime(t, v4->localTZA));
return Encode(t);
}
@@ -1029,7 +1028,7 @@ ReturnedValue DatePrototype::method_getDay(const FunctionObject *b, const Value
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
- t = WeekDay(LocalTime(t));
+ t = WeekDay(LocalTime(t, v4->localTZA));
return Encode(t);
}
@@ -1047,7 +1046,7 @@ ReturnedValue DatePrototype::method_getHours(const FunctionObject *b, const Valu
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
- t = HourFromTime(LocalTime(t));
+ t = HourFromTime(LocalTime(t, v4->localTZA));
return Encode(t);
}
@@ -1065,7 +1064,7 @@ ReturnedValue DatePrototype::method_getMinutes(const FunctionObject *b, const Va
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
- t = MinFromTime(LocalTime(t));
+ t = MinFromTime(LocalTime(t, v4->localTZA));
return Encode(t);
}
@@ -1083,7 +1082,7 @@ ReturnedValue DatePrototype::method_getSeconds(const FunctionObject *b, const Va
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
- t = SecFromTime(LocalTime(t));
+ t = SecFromTime(LocalTime(t, v4->localTZA));
return Encode(t);
}
@@ -1101,7 +1100,7 @@ ReturnedValue DatePrototype::method_getMilliseconds(const FunctionObject *b, con
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
- t = msFromTime(LocalTime(t));
+ t = msFromTime(LocalTime(t, v4->localTZA));
return Encode(t);
}
@@ -1119,7 +1118,7 @@ ReturnedValue DatePrototype::method_getTimezoneOffset(const FunctionObject *b, c
ExecutionEngine *v4 = b->engine();
double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
- t = (t - LocalTime(t)) / msPerMinute;
+ t = (t - LocalTime(t, v4->localTZA)) / msPerMinute;
return Encode(t);
}
@@ -1144,13 +1143,13 @@ ReturnedValue DatePrototype::method_setMilliseconds(const FunctionObject *b, con
if (!self)
return v4->throwTypeError();
- double t = LocalTime(self->date());
+ double t = LocalTime(self->date(), v4->localTZA);
if (v4->hasException)
return QV4::Encode::undefined();
double ms = argc ? argv[0].toNumber() : qt_qnan();
if (v4->hasException)
return QV4::Encode::undefined();
- self->setDate(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
+ self->setDate(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)), v4->localTZA)));
return Encode(self->date());
}
@@ -1178,7 +1177,7 @@ ReturnedValue DatePrototype::method_setSeconds(const FunctionObject *b, const Va
if (!self)
return v4->throwTypeError();
- double t = LocalTime(self->date());
+ double t = LocalTime(self->date(), v4->localTZA);
if (v4->hasException)
return QV4::Encode::undefined();
double sec = argc ? argv[0].toNumber() : qt_qnan();
@@ -1187,7 +1186,7 @@ ReturnedValue DatePrototype::method_setSeconds(const FunctionObject *b, const Va
double ms = (argc < 2) ? msFromTime(t) : argv[1].toNumber();
if (v4->hasException)
return QV4::Encode::undefined();
- t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
+ t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)), v4->localTZA));
self->setDate(t);
return Encode(self->date());
}
@@ -1214,7 +1213,7 @@ ReturnedValue DatePrototype::method_setMinutes(const FunctionObject *b, const Va
if (!self)
return v4->throwTypeError();
- double t = LocalTime(self->date());
+ double t = LocalTime(self->date(), v4->localTZA);
if (v4->hasException)
return QV4::Encode::undefined();
double min = argc ? argv[0].toNumber() : qt_qnan();
@@ -1226,7 +1225,7 @@ ReturnedValue DatePrototype::method_setMinutes(const FunctionObject *b, const Va
double ms = (argc < 3) ? msFromTime(t) : argv[2].toNumber();
if (v4->hasException)
return QV4::Encode::undefined();
- t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
+ t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)), v4->localTZA));
self->setDate(t);
return Encode(self->date());
}
@@ -1254,7 +1253,7 @@ ReturnedValue DatePrototype::method_setHours(const FunctionObject *b, const Valu
if (!self)
return v4->throwTypeError();
- double t = LocalTime(self->date());
+ double t = LocalTime(self->date(), v4->localTZA);
if (v4->hasException)
return QV4::Encode::undefined();
double hour = argc ? argv[0].toNumber() : qt_qnan();
@@ -1269,7 +1268,7 @@ ReturnedValue DatePrototype::method_setHours(const FunctionObject *b, const Valu
double ms = (argc < 4) ? msFromTime(t) : argv[3].toNumber();
if (v4->hasException)
return QV4::Encode::undefined();
- t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
+ t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms)), v4->localTZA));
self->setDate(t);
return Encode(self->date());
}
@@ -1298,13 +1297,13 @@ ReturnedValue DatePrototype::method_setDate(const FunctionObject *b, const Value
if (!self)
return v4->throwTypeError();
- double t = LocalTime(self->date());
+ double t = LocalTime(self->date(), v4->localTZA);
if (v4->hasException)
return QV4::Encode::undefined();
double date = argc ? argv[0].toNumber() : qt_qnan();
if (v4->hasException)
return QV4::Encode::undefined();
- t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
+ t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)), v4->localTZA));
self->setDate(t);
return Encode(self->date());
}
@@ -1334,7 +1333,7 @@ ReturnedValue DatePrototype::method_setMonth(const FunctionObject *b, const Valu
if (!self)
return v4->throwTypeError();
- double t = LocalTime(self->date());
+ double t = LocalTime(self->date(), v4->localTZA);
if (v4->hasException)
return QV4::Encode::undefined();
double month = argc ? argv[0].toNumber() : qt_qnan();
@@ -1343,7 +1342,7 @@ ReturnedValue DatePrototype::method_setMonth(const FunctionObject *b, const Valu
double date = (argc < 2) ? DateFromTime(t) : argv[1].toNumber();
if (v4->hasException)
return QV4::Encode::undefined();
- t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
+ t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)), v4->localTZA));
self->setDate(t);
return Encode(self->date());
}
@@ -1374,7 +1373,7 @@ ReturnedValue DatePrototype::method_setYear(const FunctionObject *b, const Value
if (std::isnan(t))
t = 0;
else
- t = LocalTime(t);
+ t = LocalTime(t, v4->localTZA);
double year = argc ? argv[0].toNumber() : qt_qnan();
double r;
if (std::isnan(year)) {
@@ -1383,7 +1382,7 @@ ReturnedValue DatePrototype::method_setYear(const FunctionObject *b, const Value
if ((Primitive::toInteger(year) >= 0) && (Primitive::toInteger(year) <= 99))
year += 1900;
r = MakeDay(year, MonthFromTime(t), DateFromTime(t));
- r = UTC(MakeDate(r, TimeWithinDay(t)));
+ r = UTC(MakeDate(r, TimeWithinDay(t)), v4->localTZA);
r = TimeClip(r);
}
self->setDate(r);
@@ -1413,7 +1412,7 @@ ReturnedValue DatePrototype::method_setFullYear(const FunctionObject *b, const V
if (!self)
return v4->throwTypeError();
- double t = LocalTime(self->date());
+ double t = LocalTime(self->date(), v4->localTZA);
if (v4->hasException)
return QV4::Encode::undefined();
if (std::isnan(t))
@@ -1427,7 +1426,7 @@ ReturnedValue DatePrototype::method_setFullYear(const FunctionObject *b, const V
double date = (argc < 3) ? DateFromTime(t) : argv[2].toNumber();
if (v4->hasException)
return QV4::Encode::undefined();
- t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
+ t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)), v4->localTZA));
self->setDate(t);
return Encode(self->date());
}
@@ -1518,7 +1517,7 @@ ReturnedValue DatePrototype::method_toJSON(const FunctionObject *b, const Value
return toIso->call(O, nullptr, 0);
}
-void DatePrototype::timezoneUpdated()
+void DatePrototype::timezoneUpdated(ExecutionEngine *e)
{
- LocalTZA = getLocalTZA();
+ e->localTZA = getLocalTZA();
}
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 0750d3bc75..1ee514f599 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -170,7 +170,7 @@ struct DatePrototype: Object
static ReturnedValue method_toISOString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_toJSON(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
- static void timezoneUpdated();
+ static void timezoneUpdated(ExecutionEngine *e);
};
}
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 30e589919c..eaf1fae1af 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -540,6 +540,7 @@ public:
QV4::ReturnedValue global();
+ double localTZA = 0.0; // local timezone, initialized at startup
private:
#if QT_CONFIG(qml_debug)
QScopedPointer<QV4::Debugging::Debugger> m_debugger;
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index cea0790280..f17f0fb77a 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -350,7 +350,7 @@ ReturnedValue QQmlDateExtension::method_timeZoneUpdated(const QV4::FunctionObjec
if (argc != 0)
THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments");
- QV4::DatePrototype::timezoneUpdated();
+ QV4::DatePrototype::timezoneUpdated(scope.engine);
RETURN_UNDEFINED();
}