DateMath.cpp should not depend on JavaScriptCore
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Nov 2011 00:04:53 +0000 (00:04 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Nov 2011 00:04:53 +0000 (00:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=71747

Reviewed by Darin Adler.

This patch moves the JSC-specific parts of DateMath into JSDateMath in
JavaScriptCore.  There shouldn't be any behavior change.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.gypi:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* runtime/DateConstructor.cpp:
* runtime/DateConversion.cpp:
* runtime/DateInstance.cpp:
* runtime/DateInstanceCache.h:
* runtime/DatePrototype.cpp:
* runtime/InitializeThreading.cpp:
* runtime/JSDateMath.cpp: Copied from Source/JavaScriptCore/wtf/DateMath.cpp.
(JSC::timeToMS):
(JSC::msToSeconds):
* runtime/JSDateMath.h: Copied from Source/JavaScriptCore/wtf/DateMath.h.
* wtf/DateMath.cpp:
(WTF::isLeapYear):
(WTF::msToDays):
(WTF::msToMinutes):
(WTF::msToHours):
(WTF::parseDateFromNullTerminatedCharacters):
(WTF::makeRFC2822DateString):
* wtf/DateMath.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@100205 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/GNUmakefile.list.am
Source/JavaScriptCore/JavaScriptCore.gypi
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Target.pri
Source/JavaScriptCore/runtime/DateConstructor.cpp
Source/JavaScriptCore/runtime/DateConversion.cpp
Source/JavaScriptCore/runtime/DateInstance.cpp
Source/JavaScriptCore/runtime/DateInstanceCache.h
Source/JavaScriptCore/runtime/DatePrototype.cpp
Source/JavaScriptCore/runtime/InitializeThreading.cpp
Source/JavaScriptCore/runtime/JSDateMath.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSDateMath.h [new file with mode: 0644]
Source/JavaScriptCore/wtf/DateMath.cpp
Source/JavaScriptCore/wtf/DateMath.h

index ead85f7..faad710 100644 (file)
@@ -146,6 +146,7 @@ SET(JavaScriptCore_SOURCES
     runtime/JSArray.cpp
     runtime/JSByteArray.cpp
     runtime/JSCell.cpp
+    runtime/JSDateMath.cpp
     runtime/JSFunction.cpp
     runtime/JSBoundFunction.cpp
     runtime/JSGlobalData.cpp
index 16a86b0..506a3ac 100644 (file)
@@ -1,3 +1,38 @@
+2011-11-14  Adam Barth  <abarth@webkit.org>
+
+        DateMath.cpp should not depend on JavaScriptCore
+        https://bugs.webkit.org/show_bug.cgi?id=71747
+
+        Reviewed by Darin Adler.
+
+        This patch moves the JSC-specific parts of DateMath into JSDateMath in
+        JavaScriptCore.  There shouldn't be any behavior change.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Target.pri:
+        * runtime/DateConstructor.cpp:
+        * runtime/DateConversion.cpp:
+        * runtime/DateInstance.cpp:
+        * runtime/DateInstanceCache.h:
+        * runtime/DatePrototype.cpp:
+        * runtime/InitializeThreading.cpp:
+        * runtime/JSDateMath.cpp: Copied from Source/JavaScriptCore/wtf/DateMath.cpp.
+        (JSC::timeToMS):
+        (JSC::msToSeconds):
+        * runtime/JSDateMath.h: Copied from Source/JavaScriptCore/wtf/DateMath.h.
+        * wtf/DateMath.cpp:
+        (WTF::isLeapYear):
+        (WTF::msToDays):
+        (WTF::msToMinutes):
+        (WTF::msToHours):
+        (WTF::parseDateFromNullTerminatedCharacters):
+        (WTF::makeRFC2822DateString):
+        * wtf/DateMath.h:
+
 2011-11-14  Michael Saboff  <msaboff@apple.com>
 
         Towards 8 bit strings - Add 8 bit handling to JSString Ropes
index 3529dad..47222ad 100644 (file)
@@ -380,6 +380,8 @@ javascriptcore_sources += \
        Source/JavaScriptCore/runtime/JSByteArray.h \
        Source/JavaScriptCore/runtime/JSCell.cpp \
        Source/JavaScriptCore/runtime/JSCell.h \
+       Source/JavaScriptCore/runtime/JSDateMath.cpp \
+       Source/JavaScriptCore/runtime/JSDateMath.h \
        Source/JavaScriptCore/runtime/JSFunction.cpp \
        Source/JavaScriptCore/runtime/JSFunction.h \
        Source/JavaScriptCore/runtime/JSBoundFunction.cpp \
index 70b7eff..113d4a1 100644 (file)
@@ -83,6 +83,7 @@
             'runtime/JSArray.h',
             'runtime/JSByteArray.h',
             'runtime/JSCell.h',
+            'runtime/JSDateMath.h',
             'runtime/JSFunction.h',
             'runtime/JSBoundFunction.h',
             'runtime/JSGlobalData.h',
             'runtime/JSArray.cpp',
             'runtime/JSByteArray.cpp',
             'runtime/JSCell.cpp',
+            'runtime/JSDateMath.cpp',
             'runtime/JSFunction.cpp',
             'runtime/JSBoundFunction.cpp',
             'runtime/JSGlobalData.cpp',
index 88cb4ea..124fbf3 100644 (file)
                                >
                        </File>
                        <File
+                               RelativePath="..\..\runtime\JSDateMath.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\runtime\JSDateMath.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\runtime\JSFunction.cpp"
                                >
                        </File>
index b74b60f..62656d2 100644 (file)
                969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07950ED1D3AE00F1F681 /* Opcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                96DD73790F9DA3100027FBCC /* VMTags.h in Headers */ = {isa = PBXBuildFile; fileRef = 96DD73780F9DA3100027FBCC /* VMTags.h */; settings = {ATTRIBUTES = (Private, ); }; };
                971EDEA61169E0D3005E4262 /* Terminator.h in Headers */ = {isa = PBXBuildFile; fileRef = 97F6903A1169DF7F00A6BB46 /* Terminator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               978801401471AD920041B016 /* JSDateMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9788FC221471AD0C0068CE2D /* JSDateMath.cpp */; };
+               978801411471AD920041B016 /* JSDateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9788FC231471AD0C0068CE2D /* JSDateMath.h */; settings = {ATTRIBUTES = (Private, ); }; };
                97941A5713029AAB004A3447 /* OSRandomSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97941A3F130299DB004A3447 /* OSRandomSource.cpp */; };
                97941A5A13029ACC004A3447 /* OSRandomSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 97941A40130299DB004A3447 /* OSRandomSource.h */; };
                97941A7E1302A098004A3447 /* CryptographicallyRandomNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97941A7C1302A098004A3447 /* CryptographicallyRandomNumber.cpp */; };
                969A07950ED1D3AE00F1F681 /* Opcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Opcode.h; sourceTree = "<group>"; };
                969A09220ED1E09C00F1F681 /* Completion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Completion.cpp; sourceTree = "<group>"; };
                96DD73780F9DA3100027FBCC /* VMTags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMTags.h; sourceTree = "<group>"; };
+               9788FC221471AD0C0068CE2D /* JSDateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDateMath.cpp; sourceTree = "<group>"; };
+               9788FC231471AD0C0068CE2D /* JSDateMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDateMath.h; sourceTree = "<group>"; };
                97941A3F130299DB004A3447 /* OSRandomSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OSRandomSource.cpp; sourceTree = "<group>"; };
                97941A40130299DB004A3447 /* OSRandomSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSRandomSource.h; sourceTree = "<group>"; };
                97941A7C1302A098004A3447 /* CryptographicallyRandomNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptographicallyRandomNumber.cpp; sourceTree = "<group>"; };
                                A791EF260F11E07900AE1F68 /* JSByteArray.h */,
                                BC7F8FBA0E19D1EF008632C0 /* JSCell.cpp */,
                                BC1167D80E19BCC9008066DD /* JSCell.h */,
+                               9788FC221471AD0C0068CE2D /* JSDateMath.cpp */,
+                               9788FC231471AD0C0068CE2D /* JSDateMath.h */,
                                F692A85E0255597D01FF60F7 /* JSFunction.cpp */,
                                F692A85F0255597D01FF60F7 /* JSFunction.h */,
                                E18E3A570DF9278C00D90B34 /* JSGlobalData.cpp */,
                                0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */,
                                0F431738146BAC69007E3890 /* ListableHandler.h in Headers */,
                                0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */,
+                               978801411471AD920041B016 /* JSDateMath.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */,
                                0FC0979E146B272100CF2442 /* DFGCorrectableJumpPoint.cpp in Sources */,
                                0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
+                               978801401471AD920041B016 /* JSDateMath.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 0b00630..af91490 100644 (file)
@@ -164,6 +164,7 @@ SOURCES += \
     runtime/JSArray.cpp \
     runtime/JSByteArray.cpp \
     runtime/JSCell.cpp \
+    runtime/JSDateMath.cpp \
     runtime/JSFunction.cpp \
     runtime/JSBoundFunction.cpp \
     runtime/JSGlobalData.cpp \
index 5c8d21a..931899e 100644 (file)
@@ -25,6 +25,7 @@
 #include "DateConversion.h"
 #include "DateInstance.h"
 #include "DatePrototype.h"
+#include "JSDateMath.h"
 #include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
@@ -32,7 +33,6 @@
 #include "ObjectPrototype.h"
 #include <math.h>
 #include <time.h>
-#include <wtf/DateMath.h>
 #include <wtf/MathExtras.h>
 
 #if OS(WINCE) && !PLATFORM(QT)
index 1418876..7bc0cbc 100644 (file)
 #include "DateConversion.h"
 
 #include "CallFrame.h"
+#include "JSDateMath.h"
 #include "JSObject.h"
 #include "ScopeChain.h"
 #include "UString.h"
-#include <wtf/DateMath.h>
 #include <wtf/StringExtras.h>
 #include <wtf/text/CString.h>
 
index e09a9e8..545757b 100644 (file)
 #include "config.h"
 #include "DateInstance.h"
 
+#include "JSDateMath.h"
 #include "JSGlobalObject.h"
 
 #include <math.h>
-#include <wtf/DateMath.h>
 #include <wtf/MathExtras.h>
 
 using namespace WTF;
index cdd12cf..153582f 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef DateInstanceCache_h
 #define DateInstanceCache_h
 
-#include <wtf/DateMath.h>
+#include "JSDateMath.h"
 #include <wtf/FixedArray.h>
 #include <wtf/HashFunctions.h>
 #include <wtf/PassRefPtr.h>
index 8a3e16d..319218c 100644 (file)
@@ -27,6 +27,7 @@
 #include "DateConversion.h"
 #include "DateInstance.h"
 #include "Error.h"
+#include "JSDateMath.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
 #include "JSStringBuilder.h"
@@ -43,7 +44,6 @@
 #include <stdlib.h>
 #include <time.h>
 #include <wtf/Assertions.h>
-#include <wtf/DateMath.h>
 #include <wtf/MathExtras.h>
 #include <wtf/StringExtras.h>
 #include <wtf/UnusedParam.h>
index 8028b3a..3a371f9 100644 (file)
 #include "Heap.h"
 #include "Heuristics.h"
 #include "Identifier.h"
+#include "JSDateMath.h"
 #include "JSGlobalObject.h"
 #include "UString.h"
 #include "WriteBarrier.h"
 #include "dtoa.h"
-#include <wtf/DateMath.h>
 #include <wtf/Threading.h>
 #include <wtf/dtoa/cached-powers.h>
 
diff --git a/Source/JavaScriptCore/runtime/JSDateMath.cpp b/Source/JavaScriptCore/runtime/JSDateMath.cpp
new file mode 100644 (file)
index 0000000..8630733
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ * Copyright (C) 2010 &yet, LLC. (nate@andyet.net)
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above.  If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+
+ * Copyright 2006-2008 the V8 project authors. All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSDateMath.h"
+
+#include "Assertions.h"
+#include "ASCIICType.h"
+#include "CurrentTime.h"
+#include "JSObject.h"
+#include "MathExtras.h"
+#include "ScopeChain.h"
+#include "StdLibExtras.h"
+#include "StringExtras.h"
+
+#include <algorithm>
+#include <limits.h>
+#include <limits>
+#include <stdint.h>
+#include <time.h>
+#include <wtf/text/StringBuilder.h>
+
+#if HAVE(ERRNO_H)
+#include <errno.h>
+#endif
+
+#if OS(WINCE)
+extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t);
+extern "C" struct tm * localtime(const time_t *timer);
+#endif
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if HAVE(SYS_TIMEB_H)
+#include <sys/timeb.h>
+#endif
+
+using namespace WTF;
+
+namespace JSC {
+
+static inline double timeToMS(double hour, double min, double sec, double ms)
+{
+    return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms);
+}
+
+static inline int msToSeconds(double ms)
+{
+    double result = fmod(floor(ms / msPerSecond), secondsPerMinute);
+    if (result < 0)
+        result += secondsPerMinute;
+    return static_cast<int>(result);
+}
+
+// 0: Sunday, 1: Monday, etc.
+static inline int msToWeekDay(double ms)
+{
+    int wd = (static_cast<int>(msToDays(ms)) + 4) % 7;
+    if (wd < 0)
+        wd += 7;
+    return wd;
+}
+
+// Get the DST offset for the time passed in.
+//
+// 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 double getDSTOffset(ExecState* exec, double ms, double utcOffset)
+{
+    DSTOffsetCache& cache = exec->globalData().dstOffsetCache;
+    double start = cache.start;
+    double end = cache.end;
+
+    if (start <= ms) {
+        // If the time fits in the cached interval, return the cached offset.
+        if (ms <= end) return cache.offset;
+
+        // Compute a possible new interval end.
+        double newEnd = end + cache.increment;
+
+        if (ms <= newEnd) {
+            double endOffset = calculateDSTOffset(newEnd, utcOffset);
+            if (cache.offset == endOffset) {
+                // If the offset at the end of the new interval still matches
+                // the offset in the cache, we grow the cached time interval
+                // and return the offset.
+                cache.end = newEnd;
+                cache.increment = msPerMonth;
+                return endOffset;
+            } else {
+                double offset = calculateDSTOffset(ms, utcOffset);
+                if (offset == endOffset) {
+                    // The offset at the given time is equal to the offset at the
+                    // new end of the interval, so that means that we've just skipped
+                    // the point in time where the DST offset change occurred. Updated
+                    // the interval to reflect this and reset the increment.
+                    cache.start = ms;
+                    cache.end = newEnd;
+                    cache.increment = msPerMonth;
+                } else {
+                    // The interval contains a DST offset change and the given time is
+                    // before it. Adjust the increment to avoid a linear search for
+                    // the offset change point and change the end of the interval.
+                    cache.increment /= 3;
+                    cache.end = ms;
+                }
+                // Update the offset in the cache and return it.
+                cache.offset = offset;
+                return offset;
+            }
+        }
+    }
+
+    // Compute the DST offset for the time and shrink the cache interval
+    // to only contain the time. This allows fast repeated DST offset
+    // computations for the same time.
+    double offset = calculateDSTOffset(ms, utcOffset);
+    cache.offset = offset;
+    cache.start = ms;
+    cache.end = ms;
+    cache.increment = msPerMonth;
+    return offset;
+}
+
+/*
+ * Get the difference in milliseconds between this time zone and UTC (GMT)
+ * NOT including DST.
+ */
+double getUTCOffset(ExecState* exec)
+{
+    double utcOffset = exec->globalData().cachedUTCOffset;
+    if (!isnan(utcOffset))
+        return utcOffset;
+    exec->globalData().cachedUTCOffset = calculateUTCOffset();
+    return exec->globalData().cachedUTCOffset;
+}
+
+double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
+{
+    double day = dateToDaysFrom1970(t.year + 1900, t.month, t.monthDay);
+    double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds);
+    double result = (day * WTF::msPerDay) + ms;
+
+    if (!inputIsUTC) { // convert to UTC
+        double utcOffset = getUTCOffset(exec);
+        result -= utcOffset;
+        result -= getDSTOffset(exec, result, utcOffset);
+    }
+
+    return result;
+}
+
+// input is UTC
+void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm)
+{
+    double dstOff = 0.0;
+    double utcOff = 0.0;
+    if (!outputIsUTC) {
+        utcOff = getUTCOffset(exec);
+        dstOff = getDSTOffset(exec, ms, utcOff);
+        ms += dstOff + utcOff;
+    }
+
+    const int year = msToYear(ms);
+    tm.second   =  msToSeconds(ms);
+    tm.minute   =  msToMinutes(ms);
+    tm.hour     =  msToHours(ms);
+    tm.weekDay  =  msToWeekDay(ms);
+    tm.yearDay  =  dayInYear(ms, year);
+    tm.monthDay =  dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year));
+    tm.month    =  monthFromDayInYear(tm.yearDay, isLeapYear(year));
+    tm.year     =  year - 1900;
+    tm.isDST    =  dstOff != 0.0;
+    tm.utcOffset = static_cast<long>((dstOff + utcOff) / WTF::msPerSecond);
+    tm.timeZone = nullptr;
+}
+
+double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateString)
+{
+    ASSERT(exec);
+    bool haveTZ;
+    int offset;
+    double ms = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
+    if (isnan(ms))
+        return std::numeric_limits<double>::quiet_NaN();
+
+    // fall back to local timezone
+    if (!haveTZ) {
+        double utcOffset = getUTCOffset(exec);
+        double dstOffset = getDSTOffset(exec, ms, utcOffset);
+        offset = static_cast<int>((utcOffset + dstOffset) / WTF::msPerMinute);
+    }
+    return ms - (offset * WTF::msPerMinute);
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSDateMath.h b/Source/JavaScriptCore/runtime/JSDateMath.h
new file mode 100644 (file)
index 0000000..ba6d647
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Research In Motion Limited. All rights reserved.
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#ifndef JSDateMath_h
+#define JSDateMath_h
+
+#include <wtf/DateMath.h>
+
+namespace JSC {
+
+class ExecState;
+struct GregorianDateTime;
+
+void msToGregorianDateTime(ExecState*, double, bool outputIsUTC, GregorianDateTime&);
+double gregorianDateTimeToMS(ExecState*, const GregorianDateTime&, double, bool inputIsUTC);
+double getUTCOffset(ExecState*);
+double parseDateFromNullTerminatedCharacters(ExecState*, const char* dateString);
+
+// Intentionally overridding the default tm of the system.
+// The members of tm differ on various operating systems.
+struct GregorianDateTime {
+    WTF_MAKE_NONCOPYABLE(GregorianDateTime);
+public:
+    GregorianDateTime()
+        : second(0)
+        , minute(0)
+        , hour(0)
+        , weekDay(0)
+        , monthDay(0)
+        , yearDay(0)
+        , month(0)
+        , year(0)
+        , isDST(0)
+        , utcOffset(0)
+    {
+    }
+
+    GregorianDateTime(ExecState* exec, const tm& inTm)
+        : second(inTm.tm_sec)
+        , minute(inTm.tm_min)
+        , hour(inTm.tm_hour)
+        , weekDay(inTm.tm_wday)
+        , monthDay(inTm.tm_mday)
+        , yearDay(inTm.tm_yday)
+        , month(inTm.tm_mon)
+        , year(inTm.tm_year)
+        , isDST(inTm.tm_isdst)
+    {
+        UNUSED_PARAM(exec);
+#if HAVE(TM_GMTOFF)
+        utcOffset = static_cast<int>(inTm.tm_gmtoff);
+#else
+        utcOffset = static_cast<int>(getUTCOffset(exec) / WTF::msPerSecond + (isDST ? WTF::secondsPerHour : 0));
+#endif
+
+#if HAVE(TM_ZONE)
+        int inZoneSize = strlen(inTm.tm_zone) + 1;
+        timeZone = adoptArrayPtr(new char[inZoneSize]);
+        strncpy(timeZone.get(), inTm.tm_zone, inZoneSize);
+#else
+        timeZone = nullptr;
+#endif
+    }
+
+    operator tm() const
+    {
+        tm ret;
+        memset(&ret, 0, sizeof(ret));
+
+        ret.tm_sec   =  second;
+        ret.tm_min   =  minute;
+        ret.tm_hour  =  hour;
+        ret.tm_wday  =  weekDay;
+        ret.tm_mday  =  monthDay;
+        ret.tm_yday  =  yearDay;
+        ret.tm_mon   =  month;
+        ret.tm_year  =  year;
+        ret.tm_isdst =  isDST;
+
+#if HAVE(TM_GMTOFF)
+        ret.tm_gmtoff = static_cast<long>(utcOffset);
+#endif
+#if HAVE(TM_ZONE)
+        ret.tm_zone = timeZone.get();
+#endif
+
+        return ret;
+    }
+
+    void copyFrom(const GregorianDateTime& rhs)
+    {
+        second = rhs.second;
+        minute = rhs.minute;
+        hour = rhs.hour;
+        weekDay = rhs.weekDay;
+        monthDay = rhs.monthDay;
+        yearDay = rhs.yearDay;
+        month = rhs.month;
+        year = rhs.year;
+        isDST = rhs.isDST;
+        utcOffset = rhs.utcOffset;
+        if (rhs.timeZone) {
+            int inZoneSize = strlen(rhs.timeZone.get()) + 1;
+            timeZone = adoptArrayPtr(new char[inZoneSize]);
+            strncpy(timeZone.get(), rhs.timeZone.get(), inZoneSize);
+        } else
+            timeZone = nullptr;
+    }
+
+    int second;
+    int minute;
+    int hour;
+    int weekDay;
+    int monthDay;
+    int yearDay;
+    int month;
+    int year;
+    int isDST;
+    int utcOffset;
+    OwnArrayPtr<char> timeZone;
+};
+
+static inline int gmtoffset(const GregorianDateTime& t)
+{
+    return t.utcOffset;
+}
+
+} // namespace JSC
+
+#endif // JSDateMath_h
index 9c6748b..661a86b 100644 (file)
 #include "Assertions.h"
 #include "ASCIICType.h"
 #include "CurrentTime.h"
-#if USE(JSC)
-#include "JSObject.h"
-#endif
 #include "MathExtras.h"
-#if USE(JSC)
-#include "ScopeChain.h"
-#endif
 #include "StdLibExtras.h"
 #include "StringExtras.h"
 
@@ -109,10 +103,6 @@ extern "C" struct tm * localtime(const time_t *timer);
 #include <sys/timeb.h>
 #endif
 
-#if USE(JSC)
-#include "CallFrame.h"
-#endif
-
 using namespace WTF;
 
 namespace WTF {
@@ -138,7 +128,7 @@ static const int firstDayOfMonth[2][12] = {
     {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
 };
 
-static inline bool isLeapYear(int year)
+bool isLeapYear(int year)
 {
     if (year % 4 != 0)
         return false;
@@ -173,7 +163,7 @@ static inline double daysFrom1970ToYear(int year)
     return 365.0 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule;
 }
 
-static inline double msToDays(double ms)
+double msToDays(double ms)
 {
     return floor(ms / msPerDay);
 }
@@ -210,24 +200,7 @@ static inline double msToMilliseconds(double ms)
     return result;
 }
 
-// 0: Sunday, 1: Monday, etc.
-static inline int msToWeekDay(double ms)
-{
-    int wd = (static_cast<int>(msToDays(ms)) + 4) % 7;
-    if (wd < 0)
-        wd += 7;
-    return wd;
-}
-
-static inline int msToSeconds(double ms)
-{
-    double result = fmod(floor(ms / msPerSecond), secondsPerMinute);
-    if (result < 0)
-        result += secondsPerMinute;
-    return static_cast<int>(result);
-}
-
-static inline int msToMinutes(double ms)
+int msToMinutes(double ms)
 {
     double result = fmod(floor(ms / msPerMinute), minutesPerHour);
     if (result < 0)
@@ -235,7 +208,7 @@ static inline int msToMinutes(double ms)
     return static_cast<int>(result);
 }
 
-static inline int msToHours(double ms)
+int msToHours(double ms)
 {
     double result = fmod(floor(ms/msPerHour), hoursPerDay);
     if (result < 0)
@@ -319,11 +292,6 @@ static inline int monthToDayInYear(int month, bool isLeapYear)
     return firstDayOfMonth[isLeapYear][month];
 }
 
-static inline double timeToMS(double hour, double min, double sec, double ms)
-{
-    return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms);
-}
-
 double dateToDaysFrom1970(int year, int month, int day)
 {
     year += month / 12;
@@ -724,7 +692,7 @@ double parseES5DateFromNullTerminatedCharacters(const char* dateString)
 }
 
 // Odd case where 'exec' is allowed to be 0, to accomodate a caller in WebCore.
-static double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset)
+double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset)
 {
     haveTZ = false;
     offset = 0;
@@ -1048,143 +1016,5 @@ String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, u
 
     return stringBuilder.toString();
 }
-} // namespace WTF
 
-#if USE(JSC)
-namespace JSC {
-
-// Get the DST offset for the time passed in.
-//
-// 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 double getDSTOffset(ExecState* exec, double ms, double utcOffset)
-{
-    DSTOffsetCache& cache = exec->globalData().dstOffsetCache;
-    double start = cache.start;
-    double end = cache.end;
-
-    if (start <= ms) {
-        // If the time fits in the cached interval, return the cached offset.
-        if (ms <= end) return cache.offset;
-
-        // Compute a possible new interval end.
-        double newEnd = end + cache.increment;
-
-        if (ms <= newEnd) {
-            double endOffset = calculateDSTOffset(newEnd, utcOffset);
-            if (cache.offset == endOffset) {
-                // If the offset at the end of the new interval still matches
-                // the offset in the cache, we grow the cached time interval
-                // and return the offset.
-                cache.end = newEnd;
-                cache.increment = msPerMonth;
-                return endOffset;
-            } else {
-                double offset = calculateDSTOffset(ms, utcOffset);
-                if (offset == endOffset) {
-                    // The offset at the given time is equal to the offset at the
-                    // new end of the interval, so that means that we've just skipped
-                    // the point in time where the DST offset change occurred. Updated
-                    // the interval to reflect this and reset the increment.
-                    cache.start = ms;
-                    cache.end = newEnd;
-                    cache.increment = msPerMonth;
-                } else {
-                    // The interval contains a DST offset change and the given time is
-                    // before it. Adjust the increment to avoid a linear search for
-                    // the offset change point and change the end of the interval.
-                    cache.increment /= 3;
-                    cache.end = ms;
-                }
-                // Update the offset in the cache and return it.
-                cache.offset = offset;
-                return offset;
-            }
-        }
-    }
-
-    // Compute the DST offset for the time and shrink the cache interval
-    // to only contain the time. This allows fast repeated DST offset
-    // computations for the same time.
-    double offset = calculateDSTOffset(ms, utcOffset);
-    cache.offset = offset;
-    cache.start = ms;
-    cache.end = ms;
-    cache.increment = msPerMonth;
-    return offset;
-}
-
-/*
- * Get the difference in milliseconds between this time zone and UTC (GMT)
- * NOT including DST.
- */
-double getUTCOffset(ExecState* exec)
-{
-    double utcOffset = exec->globalData().cachedUTCOffset;
-    if (!isnan(utcOffset))
-        return utcOffset;
-    exec->globalData().cachedUTCOffset = calculateUTCOffset();
-    return exec->globalData().cachedUTCOffset;
-}
-
-double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
-{
-    double day = dateToDaysFrom1970(t.year + 1900, t.month, t.monthDay);
-    double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds);
-    double result = (day * WTF::msPerDay) + ms;
-
-    if (!inputIsUTC) { // convert to UTC
-        double utcOffset = getUTCOffset(exec);
-        result -= utcOffset;
-        result -= getDSTOffset(exec, result, utcOffset);
-    }
-
-    return result;
-}
-
-// input is UTC
-void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm)
-{
-    double dstOff = 0.0;
-    double utcOff = 0.0;
-    if (!outputIsUTC) {
-        utcOff = getUTCOffset(exec);
-        dstOff = getDSTOffset(exec, ms, utcOff);
-        ms += dstOff + utcOff;
-    }
-
-    const int year = msToYear(ms);
-    tm.second   =  msToSeconds(ms);
-    tm.minute   =  msToMinutes(ms);
-    tm.hour     =  msToHours(ms);
-    tm.weekDay  =  msToWeekDay(ms);
-    tm.yearDay  =  dayInYear(ms, year);
-    tm.monthDay =  dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year));
-    tm.month    =  monthFromDayInYear(tm.yearDay, isLeapYear(year));
-    tm.year     =  year - 1900;
-    tm.isDST    =  dstOff != 0.0;
-    tm.utcOffset = static_cast<long>((dstOff + utcOff) / WTF::msPerSecond);
-    tm.timeZone = nullptr;
-}
-
-double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateString)
-{
-    ASSERT(exec);
-    bool haveTZ;
-    int offset;
-    double ms = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
-    if (isnan(ms))
-        return std::numeric_limits<double>::quiet_NaN();
-
-    // fall back to local timezone
-    if (!haveTZ) {
-        double utcOffset = getUTCOffset(exec);
-        double dstOffset = getDSTOffset(exec, ms, utcOffset);
-        offset = static_cast<int>((utcOffset + dstOffset) / WTF::msPerMinute);
-    }
-    return ms - (offset * WTF::msPerMinute);
-}
-
-} // namespace JSC
-#endif // USE(JSC)
+} // namespace WTF
index cc2e842..114acf8 100644 (file)
 #include <wtf/UnusedParam.h>
 
 namespace WTF {
+
 void initializeDates();
 int equivalentYearForDST(int year);
 
 // Not really math related, but this is currently the only shared place to put these.
 double parseES5DateFromNullTerminatedCharacters(const char* dateString);
 double parseDateFromNullTerminatedCharacters(const char* dateString);
+double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset);
 double timeClip(double);
 // dayOfWeek: [0, 6] 0 being Monday, day: [1, 31], month: [0, 11], year: ex: 2011, hours: [0, 23], minutes: [0, 59], seconds: [0, 59], utcOffset: [-720,720]. 
 String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, unsigned year, unsigned hours, unsigned minutes, unsigned seconds, int utcOffset);
@@ -71,8 +73,8 @@ inline double jsCurrentTime()
     return floor(WTF::currentTimeMS());
 }
 
-const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
-const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+const char* const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+const char* const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
 
 const double hoursPerDay = 24.0;
 const double minutesPerHour = 60.0;
@@ -84,9 +86,14 @@ const double msPerHour = 60.0 * 60.0 * 1000.0;
 const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0;
 const double msPerMonth = 2592000000.0;
 
+bool isLeapYear(int year);
+
 // Returns the number of days from 1970-01-01 to the specified date.
 double dateToDaysFrom1970(int year, int month, int day);
 int msToYear(double ms);
+double msToDays(double ms);
+int msToMinutes(double ms);
+int msToHours(double ms);
 int dayInYear(double ms, int year);
 int monthFromDayInYear(int dayInYear, bool leapYear);
 int dayInMonthFromDayInYear(int dayInYear, bool leapYear);
@@ -97,7 +104,7 @@ double calculateDSTOffset(double ms, double utcOffset);
 
 } // namespace WTF
 
-using WTF::adoptArrayPtr;
+using WTF::isLeapYear;
 using WTF::dateToDaysFrom1970;
 using WTF::dayInMonthFromDayInYear;
 using WTF::dayInYear;
@@ -107,131 +114,13 @@ using WTF::msPerDay;
 using WTF::msPerMinute;
 using WTF::msPerSecond;
 using WTF::msToYear;
+using WTF::msToDays;
+using WTF::msToMinutes;
+using WTF::msToHours;
 using WTF::secondsPerMinute;
 using WTF::parseDateFromNullTerminatedCharacters;
 using WTF::makeRFC2822DateString;
 using WTF::calculateUTCOffset;
 using WTF::calculateDSTOffset;
 
-#if USE(JSC)
-namespace JSC {
-class ExecState;
-struct GregorianDateTime;
-
-void msToGregorianDateTime(ExecState*, double, bool outputIsUTC, GregorianDateTime&);
-double gregorianDateTimeToMS(ExecState*, const GregorianDateTime&, double, bool inputIsUTC);
-double getUTCOffset(ExecState*);
-double parseDateFromNullTerminatedCharacters(ExecState*, const char* dateString);
-
-// Intentionally overridding the default tm of the system.
-// The members of tm differ on various operating systems.
-struct GregorianDateTime {
-    WTF_MAKE_NONCOPYABLE(GregorianDateTime);
-public:
-    GregorianDateTime()
-        : second(0)
-        , minute(0)
-        , hour(0)
-        , weekDay(0)
-        , monthDay(0)
-        , yearDay(0)
-        , month(0)
-        , year(0)
-        , isDST(0)
-        , utcOffset(0)
-    {
-    }
-
-    GregorianDateTime(ExecState* exec, const tm& inTm)
-        : second(inTm.tm_sec)
-        , minute(inTm.tm_min)
-        , hour(inTm.tm_hour)
-        , weekDay(inTm.tm_wday)
-        , monthDay(inTm.tm_mday)
-        , yearDay(inTm.tm_yday)
-        , month(inTm.tm_mon)
-        , year(inTm.tm_year)
-        , isDST(inTm.tm_isdst)
-    {
-        UNUSED_PARAM(exec);
-#if HAVE(TM_GMTOFF)
-        utcOffset = static_cast<int>(inTm.tm_gmtoff);
-#else
-        utcOffset = static_cast<int>(getUTCOffset(exec) / WTF::msPerSecond + (isDST ? WTF::secondsPerHour : 0));
-#endif
-
-#if HAVE(TM_ZONE)
-        int inZoneSize = strlen(inTm.tm_zone) + 1;
-        timeZone = adoptArrayPtr(new char[inZoneSize]);
-        strncpy(timeZone.get(), inTm.tm_zone, inZoneSize);
-#else
-        timeZone = nullptr;
-#endif
-    }
-
-    operator tm() const
-    {
-        tm ret;
-        memset(&ret, 0, sizeof(ret));
-
-        ret.tm_sec   =  second;
-        ret.tm_min   =  minute;
-        ret.tm_hour  =  hour;
-        ret.tm_wday  =  weekDay;
-        ret.tm_mday  =  monthDay;
-        ret.tm_yday  =  yearDay;
-        ret.tm_mon   =  month;
-        ret.tm_year  =  year;
-        ret.tm_isdst =  isDST;
-
-#if HAVE(TM_GMTOFF)
-        ret.tm_gmtoff = static_cast<long>(utcOffset);
-#endif
-#if HAVE(TM_ZONE)
-        ret.tm_zone = timeZone.get();
-#endif
-
-        return ret;
-    }
-
-    void copyFrom(const GregorianDateTime& rhs)
-    {
-        second = rhs.second;
-        minute = rhs.minute;
-        hour = rhs.hour;
-        weekDay = rhs.weekDay;
-        monthDay = rhs.monthDay;
-        yearDay = rhs.yearDay;
-        month = rhs.month;
-        year = rhs.year;
-        isDST = rhs.isDST;
-        utcOffset = rhs.utcOffset;
-        if (rhs.timeZone) {
-            int inZoneSize = strlen(rhs.timeZone.get()) + 1;
-            timeZone = adoptArrayPtr(new char[inZoneSize]);
-            strncpy(timeZone.get(), rhs.timeZone.get(), inZoneSize);
-        } else
-            timeZone = nullptr;
-    }
-
-    int second;
-    int minute;
-    int hour;
-    int weekDay;
-    int monthDay;
-    int yearDay;
-    int month;
-    int year;
-    int isDST;
-    int utcOffset;
-    OwnArrayPtr<char> timeZone;
-};
-
-static inline int gmtoffset(const GregorianDateTime& t)
-{
-    return t.utcOffset;
-}
-} // namespace JSC
-#endif // USE(JSC)
-
 #endif // DateMath_h