| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // ------------------------------------------------------------------- | 5 // ------------------------------------------------------------------- |
| 6 | 6 |
| 7 (function(global, utils) { | 7 (function(global, utils) { |
| 8 | 8 |
| 9 "use strict"; | 9 "use strict"; |
| 10 | 10 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 if (t == timezone_cache_time) { | 42 if (t == timezone_cache_time) { |
| 43 return timezone_cache_timezone; | 43 return timezone_cache_timezone; |
| 44 } | 44 } |
| 45 var timezone = %DateLocalTimezone(t); | 45 var timezone = %DateLocalTimezone(t); |
| 46 timezone_cache_time = t; | 46 timezone_cache_time = t; |
| 47 timezone_cache_timezone = timezone; | 47 timezone_cache_timezone = timezone; |
| 48 return timezone; | 48 return timezone; |
| 49 } | 49 } |
| 50 | 50 |
| 51 | 51 |
| 52 function UTC(time) { | |
| 53 if (NUMBER_IS_NAN(time)) return time; | |
| 54 // local_time_offset is needed before the call to DaylightSavingsOffset, | |
| 55 // so it may be uninitialized. | |
| 56 return %DateToUTC(time); | |
| 57 } | |
| 58 | |
| 59 | |
| 60 // ECMA 262 - 15.9.1.11 | 52 // ECMA 262 - 15.9.1.11 |
| 61 function MakeTime(hour, min, sec, ms) { | 53 function MakeTime(hour, min, sec, ms) { |
| 62 if (!IsFinite(hour)) return NaN; | 54 if (!IsFinite(hour)) return NaN; |
| 63 if (!IsFinite(min)) return NaN; | 55 if (!IsFinite(min)) return NaN; |
| 64 if (!IsFinite(sec)) return NaN; | 56 if (!IsFinite(sec)) return NaN; |
| 65 if (!IsFinite(ms)) return NaN; | 57 if (!IsFinite(ms)) return NaN; |
| 66 return TO_INTEGER(hour) * msPerHour | 58 return TO_INTEGER(hour) * msPerHour |
| 67 + TO_INTEGER(min) * msPerMinute | 59 + TO_INTEGER(min) * msPerMinute |
| 68 + TO_INTEGER(sec) * msPerSecond | 60 + TO_INTEGER(sec) * msPerSecond |
| 69 + TO_INTEGER(ms); | 61 + TO_INTEGER(ms); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 | 100 |
| 109 | 101 |
| 110 // ECMA 262 - 15.9.1.14 | 102 // ECMA 262 - 15.9.1.14 |
| 111 function TimeClip(time) { | 103 function TimeClip(time) { |
| 112 if (!IsFinite(time)) return NaN; | 104 if (!IsFinite(time)) return NaN; |
| 113 if (MathAbs(time) > MAX_TIME_MS) return NaN; | 105 if (MathAbs(time) > MAX_TIME_MS) return NaN; |
| 114 return TO_INTEGER(time) + 0; | 106 return TO_INTEGER(time) + 0; |
| 115 } | 107 } |
| 116 | 108 |
| 117 | 109 |
| 118 // The Date cache is used to limit the cost of parsing the same Date | |
| 119 // strings over and over again. | |
| 120 var Date_cache = { | |
| 121 // Cached time value. | |
| 122 time: 0, | |
| 123 // String input for which the cached time is valid. | |
| 124 string: null | |
| 125 }; | |
| 126 | |
| 127 | |
| 128 function DateConstructor(year, month, date, hours, minutes, seconds, ms) { | |
| 129 if (IS_UNDEFINED(new.target)) { | |
| 130 // ECMA 262 - 15.9.2 | |
| 131 return %_Call(DateToString, new GlobalDate()); | |
| 132 } | |
| 133 | |
| 134 // ECMA 262 - 15.9.3 | |
| 135 var argc = %_ArgumentsLength(); | |
| 136 var value; | |
| 137 var result; | |
| 138 if (argc == 0) { | |
| 139 value = %DateCurrentTime(); | |
| 140 result = %NewObject(GlobalDate, new.target); | |
| 141 SET_UTC_DATE_VALUE(result, value); | |
| 142 } else if (argc == 1) { | |
| 143 if (IS_NUMBER(year)) { | |
| 144 value = TimeClip(year); | |
| 145 | |
| 146 } else if (IS_STRING(year)) { | |
| 147 // Probe the Date cache. If we already have a time value for the | |
| 148 // given time, we re-use that instead of parsing the string again. | |
| 149 CheckDateCacheCurrent(); | |
| 150 var cache = Date_cache; | |
| 151 if (cache.string === year) { | |
| 152 value = cache.time; | |
| 153 } else { | |
| 154 value = DateParse(year); | |
| 155 if (!NUMBER_IS_NAN(value)) { | |
| 156 cache.time = value; | |
| 157 cache.string = year; | |
| 158 } | |
| 159 } | |
| 160 | |
| 161 } else if (IS_DATE(year)) { | |
| 162 value = UTC_DATE_VALUE(year); | |
| 163 | |
| 164 } else { | |
| 165 var time = TO_PRIMITIVE(year); | |
| 166 value = IS_STRING(time) ? DateParse(time) : TO_NUMBER(time); | |
| 167 } | |
| 168 result = %NewObject(GlobalDate, new.target); | |
| 169 SET_UTC_DATE_VALUE(result, value); | |
| 170 } else { | |
| 171 year = TO_NUMBER(year); | |
| 172 month = TO_NUMBER(month); | |
| 173 date = argc > 2 ? TO_NUMBER(date) : 1; | |
| 174 hours = argc > 3 ? TO_NUMBER(hours) : 0; | |
| 175 minutes = argc > 4 ? TO_NUMBER(minutes) : 0; | |
| 176 seconds = argc > 5 ? TO_NUMBER(seconds) : 0; | |
| 177 ms = argc > 6 ? TO_NUMBER(ms) : 0; | |
| 178 year = (!NUMBER_IS_NAN(year) && | |
| 179 0 <= TO_INTEGER(year) && | |
| 180 TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year; | |
| 181 var day = MakeDay(year, month, date); | |
| 182 var time = MakeTime(hours, minutes, seconds, ms); | |
| 183 value = MakeDate(day, time); | |
| 184 result = %NewObject(GlobalDate, new.target); | |
| 185 SET_LOCAL_DATE_VALUE(result, value); | |
| 186 } | |
| 187 | |
| 188 return result; | |
| 189 } | |
| 190 | |
| 191 | |
| 192 var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; | 110 var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; |
| 193 var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', | 111 var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', |
| 194 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; | 112 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; |
| 195 | 113 |
| 196 | 114 |
| 197 function TwoDigitString(value) { | 115 function TwoDigitString(value) { |
| 198 return value < 10 ? "0" + value : "" + value; | 116 return value < 10 ? "0" + value : "" + value; |
| 199 } | 117 } |
| 200 | 118 |
| 201 | 119 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 } | 171 } |
| 254 | 172 |
| 255 | 173 |
| 256 function DatePrintString(date) { | 174 function DatePrintString(date) { |
| 257 CHECK_DATE(date); | 175 CHECK_DATE(date); |
| 258 return DateString(date) + ' ' + TimeString(date); | 176 return DateString(date) + ' ' + TimeString(date); |
| 259 } | 177 } |
| 260 | 178 |
| 261 // ------------------------------------------------------------------- | 179 // ------------------------------------------------------------------- |
| 262 | 180 |
| 263 // Reused output buffer. Used when parsing date strings. | |
| 264 var parse_buffer = new InternalArray(8); | |
| 265 | |
| 266 // ECMA 262 - 15.9.4.2 | |
| 267 function DateParse(string) { | |
| 268 var arr = %DateParseString(string, parse_buffer); | |
| 269 if (IS_NULL(arr)) return NaN; | |
| 270 | |
| 271 var day = MakeDay(arr[0], arr[1], arr[2]); | |
| 272 var time = MakeTime(arr[3], arr[4], arr[5], arr[6]); | |
| 273 var date = MakeDate(day, time); | |
| 274 | |
| 275 if (IS_NULL(arr[7])) { | |
| 276 return TimeClip(UTC(date)); | |
| 277 } else { | |
| 278 return TimeClip(date - arr[7] * 1000); | |
| 279 } | |
| 280 } | |
| 281 | |
| 282 | |
| 283 // ECMA 262 - 15.9.4.3 | |
| 284 function DateUTC(year, month, date, hours, minutes, seconds, ms) { | |
| 285 year = TO_NUMBER(year); | |
| 286 month = TO_NUMBER(month); | |
| 287 var argc = %_ArgumentsLength(); | |
| 288 date = argc > 2 ? TO_NUMBER(date) : 1; | |
| 289 hours = argc > 3 ? TO_NUMBER(hours) : 0; | |
| 290 minutes = argc > 4 ? TO_NUMBER(minutes) : 0; | |
| 291 seconds = argc > 5 ? TO_NUMBER(seconds) : 0; | |
| 292 ms = argc > 6 ? TO_NUMBER(ms) : 0; | |
| 293 year = (!NUMBER_IS_NAN(year) && | |
| 294 0 <= TO_INTEGER(year) && | |
| 295 TO_INTEGER(year) <= 99) ? 1900 + TO_INTEGER(year) : year; | |
| 296 var day = MakeDay(year, month, date); | |
| 297 var time = MakeTime(hours, minutes, seconds, ms); | |
| 298 return TimeClip(MakeDate(day, time)); | |
| 299 } | |
| 300 | |
| 301 | |
| 302 // ECMA 262 - 15.9.4.4 | |
| 303 function DateNow() { | |
| 304 return %DateCurrentTime(); | |
| 305 } | |
| 306 | |
| 307 | |
| 308 // ECMA 262 - 15.9.5.2 | 181 // ECMA 262 - 15.9.5.2 |
| 309 function DateToString() { | 182 function DateToString() { |
| 310 CHECK_DATE(this); | 183 CHECK_DATE(this); |
| 311 var t = UTC_DATE_VALUE(this) | 184 var t = UTC_DATE_VALUE(this) |
| 312 if (NUMBER_IS_NAN(t)) return kInvalidDate; | 185 if (NUMBER_IS_NAN(t)) return kInvalidDate; |
| 313 var time_zone_string = LocalTimezoneString(this) | 186 var time_zone_string = LocalTimezoneString(this) |
| 314 return DatePrintString(this) + time_zone_string; | 187 return DatePrintString(this) + time_zone_string; |
| 315 } | 188 } |
| 316 | 189 |
| 317 | 190 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 | 225 |
| 353 // ECMA 262 - 15.9.5.7 | 226 // ECMA 262 - 15.9.5.7 |
| 354 function DateToLocaleTimeString() { | 227 function DateToLocaleTimeString() { |
| 355 CHECK_DATE(this); | 228 CHECK_DATE(this); |
| 356 var t = UTC_DATE_VALUE(this); | 229 var t = UTC_DATE_VALUE(this); |
| 357 if (NUMBER_IS_NAN(t)) return kInvalidDate; | 230 if (NUMBER_IS_NAN(t)) return kInvalidDate; |
| 358 return TimeString(this); | 231 return TimeString(this); |
| 359 } | 232 } |
| 360 | 233 |
| 361 | 234 |
| 362 // ECMA 262 - 15.9.5.8 | |
| 363 function DateValueOf() { | |
| 364 CHECK_DATE(this); | |
| 365 return UTC_DATE_VALUE(this); | |
| 366 } | |
| 367 | |
| 368 | |
| 369 // ECMA 262 - 15.9.5.9 | 235 // ECMA 262 - 15.9.5.9 |
| 370 function DateGetTime() { | 236 function DateGetTime() { |
| 371 CHECK_DATE(this); | 237 CHECK_DATE(this); |
| 372 return UTC_DATE_VALUE(this); | 238 return UTC_DATE_VALUE(this); |
| 373 } | 239 } |
| 374 | 240 |
| 375 | 241 |
| 376 // ECMA 262 - 15.9.5.10 | 242 // ECMA 262 - 15.9.5.10 |
| 377 function DateGetFullYear() { | 243 function DateGetFullYear() { |
| 378 CHECK_DATE(this); | 244 CHECK_DATE(this); |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 // Notice that this does not follow ECMA 262 completely. ECMA 262 | 598 // Notice that this does not follow ECMA 262 completely. ECMA 262 |
| 733 // says that toGMTString should be the same Function object as | 599 // says that toGMTString should be the same Function object as |
| 734 // toUTCString. JSC does not do this, so for compatibility we do not | 600 // toUTCString. JSC does not do this, so for compatibility we do not |
| 735 // do that either. Instead, we create a new function whose name | 601 // do that either. Instead, we create a new function whose name |
| 736 // property will return toGMTString. | 602 // property will return toGMTString. |
| 737 function DateToGMTString() { | 603 function DateToGMTString() { |
| 738 return %_Call(DateToUTCString, this); | 604 return %_Call(DateToUTCString, this); |
| 739 } | 605 } |
| 740 | 606 |
| 741 | 607 |
| 742 function PadInt(n, digits) { | |
| 743 if (digits == 1) return n; | |
| 744 return n < %_MathPow(10, digits - 1) ? '0' + PadInt(n, digits - 1) : n; | |
| 745 } | |
| 746 | |
| 747 | |
| 748 // ECMA 262 - 20.3.4.36 | |
| 749 function DateToISOString() { | |
| 750 CHECK_DATE(this); | |
| 751 var t = UTC_DATE_VALUE(this); | |
| 752 if (NUMBER_IS_NAN(t)) throw MakeRangeError(kInvalidTimeValue); | |
| 753 var year = UTC_YEAR(this); | |
| 754 var year_string; | |
| 755 if (year >= 0 && year <= 9999) { | |
| 756 year_string = PadInt(year, 4); | |
| 757 } else { | |
| 758 if (year < 0) { | |
| 759 year_string = "-" + PadInt(-year, 6); | |
| 760 } else { | |
| 761 year_string = "+" + PadInt(year, 6); | |
| 762 } | |
| 763 } | |
| 764 return year_string + | |
| 765 '-' + PadInt(UTC_MONTH(this) + 1, 2) + | |
| 766 '-' + PadInt(UTC_DAY(this), 2) + | |
| 767 'T' + PadInt(UTC_HOUR(this), 2) + | |
| 768 ':' + PadInt(UTC_MIN(this), 2) + | |
| 769 ':' + PadInt(UTC_SEC(this), 2) + | |
| 770 '.' + PadInt(UTC_MS(this), 3) + | |
| 771 'Z'; | |
| 772 } | |
| 773 | |
| 774 | |
| 775 // 20.3.4.37 Date.prototype.toJSON ( key ) | 608 // 20.3.4.37 Date.prototype.toJSON ( key ) |
| 776 function DateToJSON(key) { | 609 function DateToJSON(key) { |
| 777 var o = TO_OBJECT(this); | 610 var o = TO_OBJECT(this); |
| 778 var tv = TO_PRIMITIVE_NUMBER(o); | 611 var tv = TO_PRIMITIVE_NUMBER(o); |
| 779 if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) { | 612 if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) { |
| 780 return null; | 613 return null; |
| 781 } | 614 } |
| 782 return o.toISOString(); | 615 return o.toISOString(); |
| 783 } | 616 } |
| 784 | 617 |
| 785 | 618 |
| 786 var date_cache_version_holder; | 619 var date_cache_version_holder; |
| 787 var date_cache_version = NaN; | 620 var date_cache_version = NaN; |
| 788 | 621 |
| 789 | 622 |
| 790 function CheckDateCacheCurrent() { | 623 function CheckDateCacheCurrent() { |
| 791 if (!date_cache_version_holder) { | 624 if (!date_cache_version_holder) { |
| 792 date_cache_version_holder = %DateCacheVersion(); | 625 date_cache_version_holder = %DateCacheVersion(); |
| 793 if (!date_cache_version_holder) return; | 626 if (!date_cache_version_holder) return; |
| 794 } | 627 } |
| 795 if (date_cache_version_holder[0] == date_cache_version) { | 628 if (date_cache_version_holder[0] == date_cache_version) { |
| 796 return; | 629 return; |
| 797 } | 630 } |
| 798 date_cache_version = date_cache_version_holder[0]; | 631 date_cache_version = date_cache_version_holder[0]; |
| 799 | 632 |
| 800 // Reset the timezone cache: | 633 // Reset the timezone cache: |
| 801 timezone_cache_time = NaN; | 634 timezone_cache_time = NaN; |
| 802 timezone_cache_timezone = UNDEFINED; | 635 timezone_cache_timezone = UNDEFINED; |
| 803 | |
| 804 // Reset the date cache: | |
| 805 Date_cache.time = NaN; | |
| 806 Date_cache.string = null; | |
| 807 } | |
| 808 | |
| 809 | |
| 810 function CreateDate(time) { | |
| 811 var date = new GlobalDate(); | |
| 812 date.setTime(time); | |
| 813 return date; | |
| 814 } | 636 } |
| 815 | 637 |
| 816 // ------------------------------------------------------------------- | 638 // ------------------------------------------------------------------- |
| 817 | 639 |
| 818 %SetCode(GlobalDate, DateConstructor); | |
| 819 %FunctionSetPrototype(GlobalDate, new GlobalObject()); | 640 %FunctionSetPrototype(GlobalDate, new GlobalObject()); |
| 820 | 641 |
| 821 // Set up non-enumerable properties of the Date object itself. | |
| 822 utils.InstallFunctions(GlobalDate, DONT_ENUM, [ | |
| 823 "UTC", DateUTC, | |
| 824 "parse", DateParse, | |
| 825 "now", DateNow | |
| 826 ]); | |
| 827 | |
| 828 // Set up non-enumerable constructor property of the Date prototype object. | |
| 829 %AddNamedProperty(GlobalDate.prototype, "constructor", GlobalDate, DONT_ENUM); | |
| 830 | |
| 831 // Set up non-enumerable functions of the Date prototype object and | 642 // Set up non-enumerable functions of the Date prototype object and |
| 832 // set their names. | 643 // set their names. |
| 833 utils.InstallFunctions(GlobalDate.prototype, DONT_ENUM, [ | 644 utils.InstallFunctions(GlobalDate.prototype, DONT_ENUM, [ |
| 834 "toString", DateToString, | 645 "toString", DateToString, |
| 835 "toDateString", DateToDateString, | 646 "toDateString", DateToDateString, |
| 836 "toTimeString", DateToTimeString, | 647 "toTimeString", DateToTimeString, |
| 837 "toLocaleString", DateToLocaleString, | 648 "toLocaleString", DateToLocaleString, |
| 838 "toLocaleDateString", DateToLocaleDateString, | 649 "toLocaleDateString", DateToLocaleDateString, |
| 839 "toLocaleTimeString", DateToLocaleTimeString, | 650 "toLocaleTimeString", DateToLocaleTimeString, |
| 840 "valueOf", DateValueOf, | |
| 841 "getTime", DateGetTime, | 651 "getTime", DateGetTime, |
| 842 "getFullYear", DateGetFullYear, | 652 "getFullYear", DateGetFullYear, |
| 843 "getUTCFullYear", DateGetUTCFullYear, | 653 "getUTCFullYear", DateGetUTCFullYear, |
| 844 "getMonth", DateGetMonth, | 654 "getMonth", DateGetMonth, |
| 845 "getUTCMonth", DateGetUTCMonth, | 655 "getUTCMonth", DateGetUTCMonth, |
| 846 "getDate", DateGetDate, | 656 "getDate", DateGetDate, |
| 847 "getUTCDate", DateGetUTCDate, | 657 "getUTCDate", DateGetUTCDate, |
| 848 "getDay", DateGetDay, | 658 "getDay", DateGetDay, |
| 849 "getUTCDay", DateGetUTCDay, | 659 "getUTCDay", DateGetUTCDay, |
| 850 "getHours", DateGetHours, | 660 "getHours", DateGetHours, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 868 "setDate", DateSetDate, | 678 "setDate", DateSetDate, |
| 869 "setUTCDate", DateSetUTCDate, | 679 "setUTCDate", DateSetUTCDate, |
| 870 "setMonth", DateSetMonth, | 680 "setMonth", DateSetMonth, |
| 871 "setUTCMonth", DateSetUTCMonth, | 681 "setUTCMonth", DateSetUTCMonth, |
| 872 "setFullYear", DateSetFullYear, | 682 "setFullYear", DateSetFullYear, |
| 873 "setUTCFullYear", DateSetUTCFullYear, | 683 "setUTCFullYear", DateSetUTCFullYear, |
| 874 "toGMTString", DateToGMTString, | 684 "toGMTString", DateToGMTString, |
| 875 "toUTCString", DateToUTCString, | 685 "toUTCString", DateToUTCString, |
| 876 "getYear", DateGetYear, | 686 "getYear", DateGetYear, |
| 877 "setYear", DateSetYear, | 687 "setYear", DateSetYear, |
| 878 "toISOString", DateToISOString, | |
| 879 "toJSON", DateToJSON | 688 "toJSON", DateToJSON |
| 880 ]); | 689 ]); |
| 881 | 690 |
| 882 %InstallToContext(["create_date_fun", CreateDate]); | |
| 883 | |
| 884 }) | 691 }) |
| OLD | NEW |