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 var $createDate; | |
6 | |
7 // ------------------------------------------------------------------- | 5 // ------------------------------------------------------------------- |
8 | 6 |
9 (function(global, utils) { | 7 (function(global, utils) { |
10 | 8 |
11 "use strict"; | 9 "use strict"; |
12 | 10 |
13 %CheckIsBootstrapping(); | 11 %CheckIsBootstrapping(); |
14 | 12 |
15 // ------------------------------------------------------------------- | 13 // ------------------------------------------------------------------- |
16 // Imports | 14 // Imports |
17 | 15 |
18 var GlobalDate = global.Date; | 16 var GlobalDate = global.Date; |
19 var GlobalObject = global.Object; | 17 var GlobalObject = global.Object; |
20 var InternalArray = utils.InternalArray; | 18 var InternalArray = utils.InternalArray; |
21 var IsFinite; | 19 var IsFinite; |
22 var MathAbs; | 20 var MathAbs; |
23 var MathFloor; | 21 var MathFloor; |
| 22 var NaN = %GetRootNaN(); |
24 | 23 |
25 utils.Import(function(from) { | 24 utils.Import(function(from) { |
26 IsFinite = from.IsFinite; | 25 IsFinite = from.IsFinite; |
27 MathAbs = from.MathAbs; | 26 MathAbs = from.MathAbs; |
28 MathFloor = from.MathFloor; | 27 MathFloor = from.MathFloor; |
29 }); | 28 }); |
30 | 29 |
31 // ------------------------------------------------------------------- | 30 // ------------------------------------------------------------------- |
32 | 31 |
33 // This file contains date support implemented in JavaScript. | 32 // This file contains date support implemented in JavaScript. |
34 | 33 |
35 var timezone_cache_time = NAN; | 34 var timezone_cache_time = NaN; |
36 var timezone_cache_timezone; | 35 var timezone_cache_timezone; |
37 | 36 |
38 function LocalTimezone(t) { | 37 function LocalTimezone(t) { |
39 if (NUMBER_IS_NAN(t)) return ""; | 38 if (NUMBER_IS_NAN(t)) return ""; |
40 CheckDateCacheCurrent(); | 39 CheckDateCacheCurrent(); |
41 if (t == timezone_cache_time) { | 40 if (t == timezone_cache_time) { |
42 return timezone_cache_timezone; | 41 return timezone_cache_timezone; |
43 } | 42 } |
44 var timezone = %DateLocalTimezone(t); | 43 var timezone = %DateLocalTimezone(t); |
45 timezone_cache_time = t; | 44 timezone_cache_time = t; |
46 timezone_cache_timezone = timezone; | 45 timezone_cache_timezone = timezone; |
47 return timezone; | 46 return timezone; |
48 } | 47 } |
49 | 48 |
50 | 49 |
51 function UTC(time) { | 50 function UTC(time) { |
52 if (NUMBER_IS_NAN(time)) return time; | 51 if (NUMBER_IS_NAN(time)) return time; |
53 // local_time_offset is needed before the call to DaylightSavingsOffset, | 52 // local_time_offset is needed before the call to DaylightSavingsOffset, |
54 // so it may be uninitialized. | 53 // so it may be uninitialized. |
55 return %DateToUTC(time); | 54 return %DateToUTC(time); |
56 } | 55 } |
57 | 56 |
58 | 57 |
59 // ECMA 262 - 15.9.1.11 | 58 // ECMA 262 - 15.9.1.11 |
60 function MakeTime(hour, min, sec, ms) { | 59 function MakeTime(hour, min, sec, ms) { |
61 if (!IsFinite(hour)) return NAN; | 60 if (!IsFinite(hour)) return NaN; |
62 if (!IsFinite(min)) return NAN; | 61 if (!IsFinite(min)) return NaN; |
63 if (!IsFinite(sec)) return NAN; | 62 if (!IsFinite(sec)) return NaN; |
64 if (!IsFinite(ms)) return NAN; | 63 if (!IsFinite(ms)) return NaN; |
65 return TO_INTEGER(hour) * msPerHour | 64 return TO_INTEGER(hour) * msPerHour |
66 + TO_INTEGER(min) * msPerMinute | 65 + TO_INTEGER(min) * msPerMinute |
67 + TO_INTEGER(sec) * msPerSecond | 66 + TO_INTEGER(sec) * msPerSecond |
68 + TO_INTEGER(ms); | 67 + TO_INTEGER(ms); |
69 } | 68 } |
70 | 69 |
71 | 70 |
72 // ECMA 262 - 15.9.1.12 | 71 // ECMA 262 - 15.9.1.12 |
73 function TimeInYear(year) { | 72 function TimeInYear(year) { |
74 return DaysInYear(year) * msPerDay; | 73 return DaysInYear(year) * msPerDay; |
75 } | 74 } |
76 | 75 |
77 | 76 |
78 // Compute number of days given a year, month, date. | 77 // Compute number of days given a year, month, date. |
79 // Note that month and date can lie outside the normal range. | 78 // Note that month and date can lie outside the normal range. |
80 // For example: | 79 // For example: |
81 // MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20) | 80 // MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20) |
82 // MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1) | 81 // MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1) |
83 // MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11) | 82 // MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11) |
84 function MakeDay(year, month, date) { | 83 function MakeDay(year, month, date) { |
85 if (!IsFinite(year) || !IsFinite(month) || !IsFinite(date)) return NAN; | 84 if (!IsFinite(year) || !IsFinite(month) || !IsFinite(date)) return NaN; |
86 | 85 |
87 // Convert to integer and map -0 to 0. | 86 // Convert to integer and map -0 to 0. |
88 year = TO_INTEGER_MAP_MINUS_ZERO(year); | 87 year = TO_INTEGER_MAP_MINUS_ZERO(year); |
89 month = TO_INTEGER_MAP_MINUS_ZERO(month); | 88 month = TO_INTEGER_MAP_MINUS_ZERO(month); |
90 date = TO_INTEGER_MAP_MINUS_ZERO(date); | 89 date = TO_INTEGER_MAP_MINUS_ZERO(date); |
91 | 90 |
92 if (year < kMinYear || year > kMaxYear || | 91 if (year < kMinYear || year > kMaxYear || |
93 month < kMinMonth || month > kMaxMonth) { | 92 month < kMinMonth || month > kMaxMonth) { |
94 return NAN; | 93 return NaN; |
95 } | 94 } |
96 | 95 |
97 // Now we rely on year and month being SMIs. | 96 // Now we rely on year and month being SMIs. |
98 return %DateMakeDay(year | 0, month | 0) + date - 1; | 97 return %DateMakeDay(year | 0, month | 0) + date - 1; |
99 } | 98 } |
100 | 99 |
101 | 100 |
102 // ECMA 262 - 15.9.1.13 | 101 // ECMA 262 - 15.9.1.13 |
103 function MakeDate(day, time) { | 102 function MakeDate(day, time) { |
104 var time = day * msPerDay + time; | 103 var time = day * msPerDay + time; |
105 // Some of our runtime funtions for computing UTC(time) rely on | 104 // Some of our runtime funtions for computing UTC(time) rely on |
106 // times not being significantly larger than MAX_TIME_MS. If there | 105 // times not being significantly larger than MAX_TIME_MS. If there |
107 // is no way that the time can be within range even after UTC | 106 // is no way that the time can be within range even after UTC |
108 // conversion we return NaN immediately instead of relying on | 107 // conversion we return NaN immediately instead of relying on |
109 // TimeClip to do it. | 108 // TimeClip to do it. |
110 if (MathAbs(time) > MAX_TIME_BEFORE_UTC) return NAN; | 109 if (MathAbs(time) > MAX_TIME_BEFORE_UTC) return NaN; |
111 return time; | 110 return time; |
112 } | 111 } |
113 | 112 |
114 | 113 |
115 // ECMA 262 - 15.9.1.14 | 114 // ECMA 262 - 15.9.1.14 |
116 function TimeClip(time) { | 115 function TimeClip(time) { |
117 if (!IsFinite(time)) return NAN; | 116 if (!IsFinite(time)) return NaN; |
118 if (MathAbs(time) > MAX_TIME_MS) return NAN; | 117 if (MathAbs(time) > MAX_TIME_MS) return NaN; |
119 return TO_INTEGER(time) + 0; | 118 return TO_INTEGER(time) + 0; |
120 } | 119 } |
121 | 120 |
122 | 121 |
123 // The Date cache is used to limit the cost of parsing the same Date | 122 // The Date cache is used to limit the cost of parsing the same Date |
124 // strings over and over again. | 123 // strings over and over again. |
125 var Date_cache = { | 124 var Date_cache = { |
126 // Cached time value. | 125 // Cached time value. |
127 time: 0, | 126 time: 0, |
128 // String input for which the cached time is valid. | 127 // String input for which the cached time is valid. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 } | 257 } |
259 | 258 |
260 // ------------------------------------------------------------------- | 259 // ------------------------------------------------------------------- |
261 | 260 |
262 // Reused output buffer. Used when parsing date strings. | 261 // Reused output buffer. Used when parsing date strings. |
263 var parse_buffer = new InternalArray(8); | 262 var parse_buffer = new InternalArray(8); |
264 | 263 |
265 // ECMA 262 - 15.9.4.2 | 264 // ECMA 262 - 15.9.4.2 |
266 function DateParse(string) { | 265 function DateParse(string) { |
267 var arr = %DateParseString(string, parse_buffer); | 266 var arr = %DateParseString(string, parse_buffer); |
268 if (IS_NULL(arr)) return NAN; | 267 if (IS_NULL(arr)) return NaN; |
269 | 268 |
270 var day = MakeDay(arr[0], arr[1], arr[2]); | 269 var day = MakeDay(arr[0], arr[1], arr[2]); |
271 var time = MakeTime(arr[3], arr[4], arr[5], arr[6]); | 270 var time = MakeTime(arr[3], arr[4], arr[5], arr[6]); |
272 var date = MakeDate(day, time); | 271 var date = MakeDate(day, time); |
273 | 272 |
274 if (IS_NULL(arr[7])) { | 273 if (IS_NULL(arr[7])) { |
275 return TimeClip(UTC(date)); | 274 return TimeClip(UTC(date)); |
276 } else { | 275 } else { |
277 return TimeClip(date - arr[7] * 1000); | 276 return TimeClip(date - arr[7] * 1000); |
278 } | 277 } |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 function DateGetYear() { | 699 function DateGetYear() { |
701 CHECK_DATE(this); | 700 CHECK_DATE(this); |
702 return LOCAL_YEAR(this) - 1900; | 701 return LOCAL_YEAR(this) - 1900; |
703 } | 702 } |
704 | 703 |
705 | 704 |
706 // ECMA 262 - B.2.5 | 705 // ECMA 262 - B.2.5 |
707 function DateSetYear(year) { | 706 function DateSetYear(year) { |
708 CHECK_DATE(this); | 707 CHECK_DATE(this); |
709 year = TO_NUMBER(year); | 708 year = TO_NUMBER(year); |
710 if (NUMBER_IS_NAN(year)) return SET_UTC_DATE_VALUE(this, NAN); | 709 if (NUMBER_IS_NAN(year)) return SET_UTC_DATE_VALUE(this, NaN); |
711 year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99) | 710 year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99) |
712 ? 1900 + TO_INTEGER(year) : year; | 711 ? 1900 + TO_INTEGER(year) : year; |
713 var t = LOCAL_DATE_VALUE(this); | 712 var t = LOCAL_DATE_VALUE(this); |
714 var month, date, time; | 713 var month, date, time; |
715 if (NUMBER_IS_NAN(t)) { | 714 if (NUMBER_IS_NAN(t)) { |
716 month = 0; | 715 month = 0; |
717 date = 1; | 716 date = 1; |
718 time = 0; | 717 time = 0; |
719 } else { | 718 } else { |
720 month = LOCAL_MONTH(this); | 719 month = LOCAL_MONTH(this); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 var o = TO_OBJECT(this); | 775 var o = TO_OBJECT(this); |
777 var tv = TO_PRIMITIVE_NUMBER(o); | 776 var tv = TO_PRIMITIVE_NUMBER(o); |
778 if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) { | 777 if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) { |
779 return null; | 778 return null; |
780 } | 779 } |
781 return o.toISOString(); | 780 return o.toISOString(); |
782 } | 781 } |
783 | 782 |
784 | 783 |
785 var date_cache_version_holder; | 784 var date_cache_version_holder; |
786 var date_cache_version = NAN; | 785 var date_cache_version = NaN; |
787 | 786 |
788 | 787 |
789 function CheckDateCacheCurrent() { | 788 function CheckDateCacheCurrent() { |
790 if (!date_cache_version_holder) { | 789 if (!date_cache_version_holder) { |
791 date_cache_version_holder = %DateCacheVersion(); | 790 date_cache_version_holder = %DateCacheVersion(); |
792 if (!date_cache_version_holder) return; | 791 if (!date_cache_version_holder) return; |
793 } | 792 } |
794 if (date_cache_version_holder[0] == date_cache_version) { | 793 if (date_cache_version_holder[0] == date_cache_version) { |
795 return; | 794 return; |
796 } | 795 } |
797 date_cache_version = date_cache_version_holder[0]; | 796 date_cache_version = date_cache_version_holder[0]; |
798 | 797 |
799 // Reset the timezone cache: | 798 // Reset the timezone cache: |
800 timezone_cache_time = NAN; | 799 timezone_cache_time = NaN; |
801 timezone_cache_timezone = UNDEFINED; | 800 timezone_cache_timezone = UNDEFINED; |
802 | 801 |
803 // Reset the date cache: | 802 // Reset the date cache: |
804 Date_cache.time = NAN; | 803 Date_cache.time = NaN; |
805 Date_cache.string = null; | 804 Date_cache.string = null; |
806 } | 805 } |
807 | 806 |
808 | 807 |
809 function CreateDate(time) { | 808 function CreateDate(time) { |
810 var date = new GlobalDate(); | 809 var date = new GlobalDate(); |
811 date.setTime(time); | 810 date.setTime(time); |
812 return date; | 811 return date; |
813 } | 812 } |
814 | 813 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 "toUTCString", DateToUTCString, | 873 "toUTCString", DateToUTCString, |
875 "getYear", DateGetYear, | 874 "getYear", DateGetYear, |
876 "setYear", DateSetYear, | 875 "setYear", DateSetYear, |
877 "toISOString", DateToISOString, | 876 "toISOString", DateToISOString, |
878 "toJSON", DateToJSON | 877 "toJSON", DateToJSON |
879 ]); | 878 ]); |
880 | 879 |
881 %InstallToContext(["create_date_fun", CreateDate]); | 880 %InstallToContext(["create_date_fun", CreateDate]); |
882 | 881 |
883 }) | 882 }) |
OLD | NEW |