Changeset 16780 in webkit
- Timestamp:
- Oct 4, 2006 11:36:29 AM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r16716 r16780 1 2006-10-04 Kevin McCullough <KMcCullough@apple.com> 2 3 Reviewed by GGaren 4 5 - This is a big makeover for our Date implemenetation. This solves many platform specific issues, specifically dates before 1970, and simplifies some ugly code. The purpose of this was to get us to pass many of the JavaScriptCore tests on windows. 6 7 * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: 8 * JavaScriptCore.xcodeproj/project.pbxproj: 9 * kjs/DateMath.cpp: Added. 10 (KJS::): 11 (KJS::daysInYear): 12 (KJS::daysFrom1970ToYear): 13 (KJS::msFrom1970ToYear): 14 (KJS::msToDays): 15 (KJS::msToYear): 16 (KJS::isLeapYear): 17 (KJS::isInLeapYear): 18 (KJS::dayInYear): 19 (KJS::msToMilliseconds): 20 (KJS::msToWeekDay): 21 (KJS::msToSeconds): 22 (KJS::msToMinutes): 23 (KJS::msToHours): 24 (KJS::msToMonth): 25 (KJS::msToDayInMonth): 26 (KJS::monthToDayInYear): 27 (KJS::timeToMseconds): 28 (KJS::dateToDayInYear): 29 (KJS::equivalentYearForDST): 30 (KJS::getUTCOffset): 31 (KJS::getDSTOffsetSimple): 32 (KJS::getDSTOffset): 33 (KJS::localTimeToUTC): 34 (KJS::UTCToLocalTime): 35 (KJS::dateToMseconds): 36 (KJS::msToTM): 37 (KJS::isDST): 38 * kjs/DateMath.h: Added. 39 (KJS::): 40 * kjs/date_object.cpp: 41 (KJS::gmtoffset): 42 (KJS::formatTime): 43 (KJS::DateInstance::getTime): 44 (KJS::DateInstance::getUTCTime): 45 (KJS::DateProtoFunc::callAsFunction): 46 (KJS::DateObjectImp::construct): 47 (KJS::DateObjectFuncImp::callAsFunction): 48 (KJS::parseDate): 49 * kjs/testkjs.cpp: 50 * os-win32/stdint.h: 51 1 52 2006-10-02 Nikolas Zimmermann <zimmermann@kde.org> 2 53 -
trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
r16632 r16780 224 224 </File> 225 225 <File 226 RelativePath="..\..\kjs\DateMath.cpp" 227 > 228 </File> 229 <File 230 RelativePath="..\..\kjs\DateMath.h" 231 > 232 </File> 233 <File 226 234 RelativePath="..\..\kjs\debugger.cpp" 227 235 > -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r16621 r16780 261 261 93F0B3AC09BB4DC00068FCE3 /* Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F0B3AA09BB4DC00068FCE3 /* Parser.h */; }; 262 262 BCF655590A2049710038A194 /* MathExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF6553B0A2048DE0038A194 /* MathExtras.h */; settings = {ATTRIBUTES = (Private, ); }; }; 263 D212022A0AD4310D00ED79B6 /* DateMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D21202280AD4310C00ED79B6 /* DateMath.cpp */; }; 264 D212022B0AD4310D00ED79B6 /* DateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateMath.h */; }; 263 265 E195679609E7CF1200B89D13 /* UnicodeIcu.h in Headers */ = {isa = PBXBuildFile; fileRef = E195678F09E7CF1200B89D13 /* UnicodeIcu.h */; }; 264 266 E195679809E7CF1200B89D13 /* Unicode.h in Headers */ = {isa = PBXBuildFile; fileRef = E195679409E7CF1200B89D13 /* Unicode.h */; }; … … 516 518 93F1981A08245AAE001E9ABC /* keywords.table */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = text; path = keywords.table; sourceTree = "<group>"; tabWidth = 8; }; 517 519 BCF6553B0A2048DE0038A194 /* MathExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MathExtras.h; sourceTree = "<group>"; }; 520 D21202280AD4310C00ED79B6 /* DateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateMath.cpp; sourceTree = "<group>"; }; 521 D21202290AD4310C00ED79B6 /* DateMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateMath.h; sourceTree = "<group>"; }; 518 522 E195678F09E7CF1200B89D13 /* UnicodeIcu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnicodeIcu.h; sourceTree = "<group>"; }; 519 523 E195679409E7CF1200B89D13 /* Unicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Unicode.h; sourceTree = "<group>"; }; … … 851 855 F692A8550255597D01FF60F7 /* date_object.cpp */, 852 856 F692A8560255597D01FF60F7 /* date_object.h */, 857 D21202280AD4310C00ED79B6 /* DateMath.cpp */, 858 D21202290AD4310C00ED79B6 /* DateMath.h */, 853 859 F692A8580255597D01FF60F7 /* debugger.cpp */, 854 860 F692A8590255597D01FF60F7 /* debugger.h */, … … 1123 1129 65C7A1740A8EAACB00FA37EA /* JSWrapperObject.h in Headers */, 1124 1130 93B6A0DF0AA64DA40076DE27 /* GetPtr.h in Headers */, 1131 D212022B0AD4310D00ED79B6 /* DateMath.h in Headers */, 1125 1132 ); 1126 1133 runOnlyForDeploymentPostprocessing = 0; … … 1227 1234 isa = PBXProject; 1228 1235 buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */; 1229 compatibilityVersion = "Xcode 2.4";1230 1236 hasScannedForEncodings = 1; 1231 1237 mainGroup = 0867D691FE84028FC02AAC07 /* JavaScriptCore */; … … 1233 1239 projectDirPath = ""; 1234 1240 projectRoot = ""; 1235 shouldCheckCompatibility = 1;1236 1241 targets = ( 1237 1242 932F5B3E0822A1C700736975 /* JavaScriptCore */, … … 1412 1417 65400C110A69BAF200509887 /* PropertyNameArray.cpp in Sources */, 1413 1418 65C7A1730A8EAACB00FA37EA /* JSWrapperObject.cpp in Sources */, 1419 D212022A0AD4310D00ED79B6 /* DateMath.cpp in Sources */, 1414 1420 ); 1415 1421 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/kjs/date_object.cpp
r16164 r16780 52 52 #include "error_object.h" 53 53 #include "operations.h" 54 #include <DateMath.h> 54 55 55 56 #include <wtf/MathExtras.h> … … 57 58 58 59 #if PLATFORM(MAC) 59 #include <CoreFoundation/CoreFoundation.h> 60 #endif 60 #include <CoreFoundation/CoreFoundation.h> 61 #endif 62 63 namespace KJS { 64 65 static double parseDate(const UString&); 66 static double timeClip(double); 61 67 62 68 inline int gmtoffset(const tm& t) … … 64 70 #if PLATFORM(WIN_OS) 65 71 // Time is supposed to be in the current timezone. 66 // FIXME: Use undocumented _dstbias? 67 return -(_timezone / 60 - (t.tm_isdst > 0 ? 60 : 0 )) * 60; 72 return static_cast<int>(getUTCOffset()/1000.0); 68 73 #else 69 74 return t.tm_gmtoff; … … 71 76 } 72 77 73 namespace KJS {74 78 75 79 /** … … 90 94 int id; 91 95 }; 92 93 // some constants94 const double hoursPerDay = 24;95 const double minutesPerHour = 60;96 const double secondsPerMinute = 60;97 const double msPerSecond = 1000;98 const double msPerMinute = 60 * 1000;99 const double msPerHour = 60 * 60 * 1000;100 const double msPerDay = 24 * 60 * 60 * 1000;101 102 static const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };103 static const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };104 105 static double makeTime(tm *, double ms, bool utc);106 static double parseDate(const UString &);107 static double timeClip(double);108 static void millisecondsToTM(double milli, bool utc, tm *t);109 96 110 97 #if PLATFORM(MAC) … … 197 184 char buffer[100]; 198 185 if (utc) { 199 // FIXME: why not on windows? 200 #if !PLATFORM(WIN_OS) 186 #if !PLATFORM(WIN_OS) //win doesn't have the tm_gtoff member 201 187 ASSERT(t.tm_gmtoff == 0); 202 188 #endif … … 221 207 } 222 208 return UString(buffer); 223 }224 225 static int day(double t)226 {227 return int(floor(t / msPerDay));228 }229 230 static double dayFromYear(int year)231 {232 return 365.0 * (year - 1970)233 + floor((year - 1969) / 4.0)234 - floor((year - 1901) / 100.0)235 + floor((year - 1601) / 400.0);236 }237 238 // based on the rule for whether it's a leap year or not239 static int daysInYear(int year)240 {241 if (year % 4 != 0)242 return 365;243 if (year % 400 == 0)244 return 366;245 if (year % 100 == 0)246 return 365;247 return 366;248 }249 250 // time value of the start of a year251 static double timeFromYear(int year)252 {253 return msPerDay * dayFromYear(year);254 }255 256 // year determined by time value257 static int yearFromTime(double t)258 {259 // ### there must be an easier way260 261 // initial guess262 int y = 1970 + int(t / (365.25 * msPerDay));263 264 // adjustment265 if (timeFromYear(y) > t) {266 do267 --y;268 while (timeFromYear(y) > t);269 } else {270 while (timeFromYear(y + 1) < t)271 ++y;272 }273 274 return y;275 }276 277 // 0: Sunday, 1: Monday, etc.278 static int weekDay(double t)279 {280 int wd = (day(t) + 4) % 7;281 if (wd < 0)282 wd += 7;283 return wd;284 209 } 285 210 … … 369 294 return false; 370 295 371 m illisecondsToTM(milli, false, &t);296 msToTM(milli, false, t); 372 297 offset = gmtoffset(t); 373 298 return true; … … 380 305 return false; 381 306 382 m illisecondsToTM(milli, true, &t);307 msToTM(milli, true, t); 383 308 return true; 384 309 } … … 391 316 392 317 tm t; 393 m illisecondsToTM(milli, false, &t);318 msToTM(milli, false, t); 394 319 offset = gmtoffset(t); 395 320 return true; … … 410 335 return minusOne < 0; 411 336 } 412 413 static void millisecondsToTM(double milli, bool utc, tm *t)414 {415 // check whether time value is outside time_t's usual range416 // make the necessary transformations if necessary417 static bool time_tIsSigned = isTime_tSigned();418 static double time_tMin = (time_tIsSigned ? - (double)(1ULL << (8 * sizeof(time_t) - 1)) : 0);419 static double time_tMax = (time_tIsSigned ? (1ULL << 8 * sizeof(time_t) - 1) - 1 : 2 * (double)(1ULL << 8 * sizeof(time_t) - 1) - 1);420 int realYearOffset = 0;421 double milliOffset = 0.0;422 double secs = floor(milli / msPerSecond);423 424 if (secs < time_tMin || secs > time_tMax) {425 // ### ugly and probably not very precise426 int realYear = yearFromTime(milli);427 int base = daysInYear(realYear) == 365 ? 2001 : 2000;428 milliOffset = timeFromYear(base) - timeFromYear(realYear);429 milli += milliOffset;430 realYearOffset = realYear - base;431 }432 433 time_t tv = (time_t) floor(milli / msPerSecond);434 435 *t = *(utc ? gmtime(&tv) : localtime(&tv));436 // We had an out of range year. Restore the year (plus/minus offset437 // found by calculating tm_year) and fix the week day calculation.438 if (realYearOffset != 0) {439 t->tm_year += realYearOffset;440 milli -= milliOffset;441 // Do our own weekday calculation. Use time zone offset to handle local time.442 double m = milli;443 if (!utc)444 m += gmtoffset(*t) * msPerSecond;445 t->tm_wday = weekDay(m);446 }447 }448 449 337 450 338 // ------------------------------ DatePrototype ----------------------------- … … 576 464 577 465 tm t; 578 m illisecondsToTM(milli, utc, &t);466 msToTM(milli, utc, t); 579 467 580 468 switch (id) { … … 675 563 id == SetMinutes || id == SetHours || id == SetDate || 676 564 id == SetMonth || id == SetFullYear ) { 677 result = jsNumber( makeTime(&t, ms, utc));565 result = jsNumber(dateToMseconds(&t, ms, utc)); 678 566 thisDateObj->setInternalValue(result); 679 567 } … … 762 650 t.tm_isdst = -1; 763 651 double ms = (numArgs >= 7) ? roundValue(exec, args[6]) : 0; 764 value = makeTime(&t, ms, false);652 value = dateToMseconds(&t, ms, false); 765 653 } 766 654 } … … 815 703 t.tm_sec = (n >= 6) ? args[5]->toInt32(exec) : 0; 816 704 double ms = (n >= 7) ? roundValue(exec, args[6]) : 0; 817 return jsNumber( makeTime(&t, ms, true));705 return jsNumber(dateToMseconds(&t, ms, true)); 818 706 } 819 707 } … … 853 741 { "PDT", -420 } 854 742 }; 855 856 static double makeTime(tm *t, double ms, bool utc)857 {858 int utcOffset;859 if (utc) {860 time_t zero = 0;861 #if PLATFORM(WIN_OS)862 // FIXME: not thread safe863 (void)localtime(&zero);864 #if COMPILER(BORLAND) || COMPILER(CYGWIN)865 utcOffset = - _timezone;866 #else867 utcOffset = - timezone;868 #endif869 t->tm_isdst = 0;870 #else871 tm t3;872 localtime_r(&zero, &t3);873 utcOffset = t3.tm_gmtoff;874 t->tm_isdst = t3.tm_isdst;875 #endif876 } else {877 utcOffset = 0;878 t->tm_isdst = -1;879 }880 881 double yearOffset = 0.0;882 if (t->tm_year < (1970 - 1900) || t->tm_year > (2038 - 1900)) {883 // we'll fool mktime() into believing that this year is within884 // its normal, portable range (1970-2038) by setting tm_year to885 // 2000 or 2001 and adding the difference in milliseconds later.886 // choice between offset will depend on whether the year is a887 // leap year or not.888 int y = t->tm_year + 1900;889 int baseYear = daysInYear(y) == 365 ? 2001 : 2000;890 double baseTime = timeFromYear(baseYear);891 yearOffset = timeFromYear(y) - baseTime;892 t->tm_year = baseYear - 1900;893 }894 895 // Determine whether DST is in effect. mktime() can't do this for us because896 // it doesn't know about ms and yearOffset.897 // NOTE: Casting values of large magnitude to time_t (long) will898 // produce incorrect results, but there's no other option when calling localtime_r().899 if (!utc) {900 time_t tval = mktime(t) + (time_t)((ms + yearOffset) / 1000);901 tm t3 = *localtime(&tval);902 t->tm_isdst = t3.tm_isdst;903 }904 905 return (mktime(t) + utcOffset) * msPerSecond + ms + yearOffset;906 }907 743 908 744 inline static void skipSpacesAndComments(const char *&s) … … 1234 1070 t.tm_hour = hour; 1235 1071 1236 // Use our makeTime() rather than mktime() as the latter can't handle the full year range.1237 return makeTime(&t, 0, false);1072 // Use our dateToMseconds() rather than mktime() as the latter can't handle the full year range. 1073 return dateToMseconds(&t, 0, false); 1238 1074 } 1239 1075 -
trunk/JavaScriptCore/kjs/testkjs.cpp
r15437 r16780 32 32 #include <math.h> 33 33 #include <stdio.h> 34 34 35 #include <string.h> 35 36 #if HAVE(SYS_TIME_H) -
trunk/JavaScriptCore/os-win32/stdint.h
r13717 r16780 22 22 #define STDINT_WIN32_H 23 23 24 #include <wtf/Platform.h> 25 24 26 /* This file emulates enough of stdint.h on Windows to make JavaScriptCore and WebCore compile. */ 25 27 26 28 #if !PLATFORM(WIN_OS) 27 29 #error "This stdint.h file should only be compiled under Windows"
Note: See TracChangeset
for help on using the changeset viewer.