Commit 38c79a21 authored by akling@apple.com's avatar akling@apple.com

Pass VM instead of ExecState to JSDateMath functions.

<https://webkit.org/b/121997>

Reviewed by Geoffrey Garen.

The JSC date math functions only need the VM, so pass that from
callers instead of the whole ExecState.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156540 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e1cb20d5
2013-09-27 Andreas Kling <akling@apple.com>
Pass VM instead of ExecState to JSDateMath functions.
<https://webkit.org/b/121997>
Reviewed by Geoffrey Garen.
The JSC date math functions only need the VM, so pass that from
callers instead of the whole ExecState.
2013-09-26 Andreas Kling <akling@apple.com>
GetterSetter construction should take a VM instead of ExecState.
......@@ -106,7 +106,7 @@ JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, const Arg
else {
JSValue primitive = args.at(0).toPrimitive(exec);
if (primitive.isString())
value = parseDate(exec, primitive.getString(exec));
value = parseDate(exec->vm(), primitive.getString(exec));
else
value = primitive.toNumber(exec);
}
......@@ -139,7 +139,7 @@ JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, const Arg
t.setSecond(JSC::toInt32(doubleArguments[5]));
t.setIsDST(-1);
double ms = (numArgs >= 7) ? doubleArguments[6] : 0;
value = gregorianDateTimeToMS(exec, t, ms, false);
value = gregorianDateTimeToMS(exec->vm(), t, ms, false);
}
}
......@@ -161,9 +161,10 @@ ConstructType DateConstructor::getConstructData(JSCell*, ConstructData& construc
// ECMA 15.9.2
static EncodedJSValue JSC_HOST_CALL callDate(ExecState* exec)
{
VM& vm = exec->vm();
GregorianDateTime ts;
msToGregorianDateTime(exec, currentTimeMS(), false, ts);
return JSValue::encode(jsNontrivialString(exec, formatDateTime(ts, DateTimeFormatDateAndTime, false)));
msToGregorianDateTime(vm, currentTimeMS(), false, ts);
return JSValue::encode(jsNontrivialString(&vm, formatDateTime(ts, DateTimeFormatDateAndTime, false)));
}
CallType DateConstructor::getCallData(JSCell*, CallData& callData)
......@@ -174,7 +175,7 @@ CallType DateConstructor::getCallData(JSCell*, CallData& callData)
static EncodedJSValue JSC_HOST_CALL dateParse(ExecState* exec)
{
return JSValue::encode(jsNumber(parseDate(exec, exec->argument(0).toString(exec)->value(exec))));
return JSValue::encode(jsNumber(parseDate(exec->vm(), exec->argument(0).toString(exec)->value(exec))));
}
static EncodedJSValue JSC_HOST_CALL dateNow(ExecState*)
......@@ -212,7 +213,7 @@ static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState* exec)
t.setMinute(JSC::toInt32(doubleArguments[4]));
t.setSecond(JSC::toInt32(doubleArguments[5]));
double ms = (n >= 7) ? doubleArguments[6] : 0;
return JSValue::encode(jsNumber(timeClip(gregorianDateTimeToMS(exec, t, ms, true))));
return JSValue::encode(jsNumber(timeClip(gregorianDateTimeToMS(exec->vm(), t, ms, true))));
}
} // namespace JSC
......@@ -64,11 +64,12 @@ const GregorianDateTime* DateInstance::calculateGregorianDateTime(ExecState* exe
if (std::isnan(milli))
return 0;
VM& vm = exec->vm();
if (!m_data)
m_data = exec->vm().dateInstanceCache.add(milli);
m_data = vm.dateInstanceCache.add(milli);
if (m_data->m_gregorianDateTimeCachedForMS != milli) {
msToGregorianDateTime(exec, milli, false, m_data->m_cachedGregorianDateTime);
msToGregorianDateTime(vm, milli, false, m_data->m_cachedGregorianDateTime);
m_data->m_gregorianDateTimeCachedForMS = milli;
}
return &m_data->m_cachedGregorianDateTime;
......@@ -80,11 +81,12 @@ const GregorianDateTime* DateInstance::calculateGregorianDateTimeUTC(ExecState*
if (std::isnan(milli))
return 0;
VM& vm = exec->vm();
if (!m_data)
m_data = exec->vm().dateInstanceCache.add(milli);
m_data = vm.dateInstanceCache.add(milli);
if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) {
msToGregorianDateTime(exec, milli, true, m_data->m_cachedGregorianDateTimeUTC);
msToGregorianDateTime(vm, milli, true, m_data->m_cachedGregorianDateTimeUTC);
m_data->m_gregorianDateTimeUTCCachedForMS = milli;
}
return &m_data->m_cachedGregorianDateTimeUTC;
......
......@@ -888,10 +888,11 @@ static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse,
DateInstance* thisDateObj = asDateInstance(thisValue);
double milli = thisDateObj->internalNumber();
VM& vm = exec->vm();
if (!exec->argumentCount() || std::isnan(milli)) {
JSValue result = jsNaN();
thisDateObj->setInternalValue(exec->vm(), result);
thisDateObj->setInternalValue(vm, result);
return JSValue::encode(result);
}
......@@ -908,12 +909,12 @@ static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse,
gregorianDateTime.copyFrom(*other);
if (!fillStructuresUsingTimeArgs(exec, numArgsToUse, &ms, &gregorianDateTime)) {
JSValue result = jsNaN();
thisDateObj->setInternalValue(exec->vm(), result);
thisDateObj->setInternalValue(vm, result);
return JSValue::encode(result);
}
JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
thisDateObj->setInternalValue(exec->vm(), result);
JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputIsUTC));
thisDateObj->setInternalValue(vm, result);
return JSValue::encode(result);
}
......@@ -928,14 +929,15 @@ static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse,
JSValue result = jsNaN();
thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
}
VM& vm = exec->vm();
double milli = thisDateObj->internalNumber();
double ms = 0;
GregorianDateTime gregorianDateTime;
if (numArgsToUse == 3 && std::isnan(milli))
msToGregorianDateTime(exec, 0, true, gregorianDateTime);
msToGregorianDateTime(vm, 0, true, gregorianDateTime);
else {
ms = milli - floor(milli / msPerSecond) * msPerSecond;
const GregorianDateTime* other = inputIsUTC
......@@ -948,12 +950,12 @@ static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse,
if (!fillStructuresUsingDateArgs(exec, numArgsToUse, &ms, &gregorianDateTime)) {
JSValue result = jsNaN();
thisDateObj->setInternalValue(exec->vm(), result);
thisDateObj->setInternalValue(vm, result);
return JSValue::encode(result);
}
JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
thisDateObj->setInternalValue(exec->vm(), result);
JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, inputIsUTC));
thisDateObj->setInternalValue(vm, result);
return JSValue::encode(result);
}
......@@ -1047,10 +1049,11 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
if (!thisValue.inherits(DateInstance::info()))
return throwVMTypeError(exec);
VM& vm = exec->vm();
DateInstance* thisDateObj = asDateInstance(thisValue);
if (!exec->argumentCount()) {
JSValue result = jsNaN();
thisDateObj->setInternalValue(exec->vm(), result);
thisDateObj->setInternalValue(vm, result);
return JSValue::encode(result);
}
......@@ -1061,7 +1064,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
if (std::isnan(milli))
// Based on ECMA 262 B.2.5 (setYear)
// the time must be reset to +0 if it is NaN.
msToGregorianDateTime(exec, 0, true, gregorianDateTime);
msToGregorianDateTime(vm, 0, true, gregorianDateTime);
else {
double secs = floor(milli / msPerSecond);
ms = milli - secs * msPerSecond;
......@@ -1072,13 +1075,13 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
double year = exec->argument(0).toIntegerPreserveNaN(exec);
if (!std::isfinite(year)) {
JSValue result = jsNaN();
thisDateObj->setInternalValue(exec->vm(), result);
thisDateObj->setInternalValue(vm, result);
return JSValue::encode(result);
}
gregorianDateTime.setYear(toInt32((year >= 0 && year <= 99) ? (year + 1900) : year));
JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, false));
thisDateObj->setInternalValue(exec->vm(), result);
JSValue result = jsNumber(gregorianDateTimeToMS(vm, gregorianDateTime, ms, false));
thisDateObj->setInternalValue(vm, result);
return JSValue::encode(result);
}
......
......@@ -132,9 +132,9 @@ static inline int msToWeekDay(double ms)
// NOTE: The implementation relies on the fact that no time zones have
// more than one daylight savings offset change per month.
// If this function is called with NaN it returns NaN.
static LocalTimeOffset localTimeOffset(ExecState* exec, double ms)
static LocalTimeOffset localTimeOffset(VM& vm, double ms)
{
LocalTimeOffsetCache& cache = exec->vm().localTimeOffsetCache;
LocalTimeOffsetCache& cache = vm.localTimeOffsetCache;
double start = cache.start;
double end = cache.end;
......@@ -188,24 +188,24 @@ static LocalTimeOffset localTimeOffset(ExecState* exec, double ms)
return offset;
}
double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
double gregorianDateTimeToMS(VM& vm, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
{
double day = dateToDaysFrom1970(t.year(), t.month(), t.monthDay());
double ms = timeToMS(t.hour(), t.minute(), t.second(), milliSeconds);
double result = (day * WTF::msPerDay) + ms;
if (!inputIsUTC)
result -= localTimeOffset(exec, result).offset;
result -= localTimeOffset(vm, result).offset;
return result;
}
// input is UTC
void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm)
void msToGregorianDateTime(VM& vm, double ms, bool outputIsUTC, GregorianDateTime& tm)
{
LocalTimeOffset localTime;
if (!outputIsUTC) {
localTime = localTimeOffset(exec, ms);
localTime = localTimeOffset(vm, ms);
ms += localTime.offset;
}
......@@ -222,9 +222,8 @@ void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, Gregori
tm.setUtcOffset(localTime.offset / WTF::msPerSecond);
}
double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateString)
double parseDateFromNullTerminatedCharacters(VM& vm, const char* dateString)
{
ASSERT(exec);
bool haveTZ;
int offset;
double ms = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
......@@ -233,20 +232,20 @@ double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateSt
// fall back to local timezone
if (!haveTZ)
offset = localTimeOffset(exec, ms).offset / WTF::msPerMinute;
offset = localTimeOffset(vm, ms).offset / WTF::msPerMinute;
return ms - (offset * WTF::msPerMinute);
}
double parseDate(ExecState* exec, const String& date)
double parseDate(VM& vm, const String& date)
{
if (date == exec->vm().cachedDateString)
return exec->vm().cachedDateStringValue;
if (date == vm.cachedDateString)
return vm.cachedDateStringValue;
double value = parseES5DateFromNullTerminatedCharacters(date.utf8().data());
if (std::isnan(value))
value = parseDateFromNullTerminatedCharacters(exec, date.utf8().data());
exec->vm().cachedDateString = date;
exec->vm().cachedDateStringValue = value;
value = parseDateFromNullTerminatedCharacters(vm, date.utf8().data());
vm.cachedDateString = date;
vm.cachedDateStringValue = value;
return value;
}
......
......@@ -48,13 +48,13 @@
namespace JSC {
class ExecState;
class VM;
void msToGregorianDateTime(ExecState*, double, bool outputIsUTC, GregorianDateTime&);
double gregorianDateTimeToMS(ExecState*, const GregorianDateTime&, double, bool inputIsUTC);
double getUTCOffset(ExecState*);
double parseDateFromNullTerminatedCharacters(ExecState*, const char* dateString);
double parseDate(ExecState*, const WTF::String&);
void msToGregorianDateTime(VM&, double, bool outputIsUTC, GregorianDateTime&);
double gregorianDateTimeToMS(VM&, const GregorianDateTime&, double, bool inputIsUTC);
double getUTCOffset(VM&);
double parseDateFromNullTerminatedCharacters(VM&, const char* dateString);
double parseDate(VM&, const WTF::String&);
} // namespace JSC
......
......@@ -291,7 +291,7 @@ static void getGregorianDateTimeUTC(JSContextRef context, JSRealType type, JSVal
} else {
double ms = JSValueToNumber(context, value, exception);
GregorianDateTime convertedGdt;
msToGregorianDateTime(exec, ms, /*utc*/ true, convertedGdt);
msToGregorianDateTime(exec->vm(), ms, /*utc*/ true, convertedGdt);
gdt->copyFrom(convertedGdt);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment