2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
23 #include "DateConstructor.h"
25 #include "DateConversion.h"
26 #include "DateInstance.h"
27 #include "DatePrototype.h"
28 #include "JSDateMath.h"
29 #include "JSFunction.h"
30 #include "JSGlobalObject.h"
32 #include "ObjectPrototype.h"
33 #include "JSCInlines.h"
36 #include <wtf/MathExtras.h>
38 #if ENABLE(WEB_REPLAY)
39 #include "InputCursor.h"
40 #include "JSReplayInputs.h"
48 #include <sys/timeb.h>
55 EncodedJSValue JSC_HOST_CALL
dateParse(ExecState
*);
56 EncodedJSValue JSC_HOST_CALL
dateNow(ExecState
*);
57 EncodedJSValue JSC_HOST_CALL
dateUTC(ExecState
*);
61 #include "DateConstructor.lut.h"
65 const ClassInfo
DateConstructor::s_info
= { "Function", &InternalFunction::s_info
, &dateConstructorTable
, CREATE_METHOD_TABLE(DateConstructor
) };
67 /* Source for DateConstructor.lut.h
68 @begin dateConstructorTable
69 parse dateParse DontEnum|Function 1
70 UTC dateUTC DontEnum|Function 7
71 now dateNow DontEnum|Function 0
75 #if ENABLE(WEB_REPLAY)
76 static double deterministicCurrentTime(JSGlobalObject
* globalObject
)
78 double currentTime
= jsCurrentTime();
79 InputCursor
& cursor
= globalObject
->inputCursor();
80 if (cursor
.isCapturing())
81 cursor
.appendInput
<GetCurrentTime
>(currentTime
);
83 if (cursor
.isReplaying()) {
84 if (GetCurrentTime
* input
= cursor
.fetchInput
<GetCurrentTime
>())
85 currentTime
= input
->currentTime();
91 #if ENABLE(WEB_REPLAY)
92 #define NORMAL_OR_DETERMINISTIC_FUNCTION(a, b) (b)
94 #define NORMAL_OR_DETERMINISTIC_FUNCTION(a, b) (a)
97 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(DateConstructor
);
99 DateConstructor::DateConstructor(VM
& vm
, Structure
* structure
)
100 : InternalFunction(vm
, structure
)
104 void DateConstructor::finishCreation(VM
& vm
, DatePrototype
* datePrototype
)
106 Base::finishCreation(vm
, datePrototype
->classInfo()->className
);
107 putDirectWithoutTransition(vm
, vm
.propertyNames
->prototype
, datePrototype
, DontEnum
| DontDelete
| ReadOnly
);
108 putDirectWithoutTransition(vm
, vm
.propertyNames
->length
, jsNumber(7), ReadOnly
| DontEnum
| DontDelete
);
111 bool DateConstructor::getOwnPropertySlot(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertySlot
&slot
)
113 return getStaticFunctionSlot
<InternalFunction
>(exec
, dateConstructorTable
, jsCast
<DateConstructor
*>(object
), propertyName
, slot
);
117 JSObject
* constructDate(ExecState
* exec
, JSGlobalObject
* globalObject
, const ArgList
& args
)
120 int numArgs
= args
.size();
124 if (numArgs
== 0) // new Date() ECMA 15.9.3.3
125 value
= NORMAL_OR_DETERMINISTIC_FUNCTION(jsCurrentTime(), deterministicCurrentTime(globalObject
));
126 else if (numArgs
== 1) {
127 if (args
.at(0).inherits(DateInstance::info()))
128 value
= asDateInstance(args
.at(0))->internalNumber();
130 JSValue primitive
= args
.at(0).toPrimitive(exec
);
131 if (primitive
.isString())
132 value
= parseDate(vm
, primitive
.getString(exec
));
134 value
= primitive
.toNumber(exec
);
137 double doubleArguments
[7] = {
138 args
.at(0).toNumber(exec
),
139 args
.at(1).toNumber(exec
),
140 args
.at(2).toNumber(exec
),
141 args
.at(3).toNumber(exec
),
142 args
.at(4).toNumber(exec
),
143 args
.at(5).toNumber(exec
),
144 args
.at(6).toNumber(exec
)
146 if ((!std::isfinite(doubleArguments
[0]) || (doubleArguments
[0] > INT_MAX
) || (doubleArguments
[0] < INT_MIN
))
147 || (!std::isfinite(doubleArguments
[1]) || (doubleArguments
[1] > INT_MAX
) || (doubleArguments
[1] < INT_MIN
))
148 || (numArgs
>= 3 && (!std::isfinite(doubleArguments
[2]) || (doubleArguments
[2] > INT_MAX
) || (doubleArguments
[2] < INT_MIN
)))
149 || (numArgs
>= 4 && (!std::isfinite(doubleArguments
[3]) || (doubleArguments
[3] > INT_MAX
) || (doubleArguments
[3] < INT_MIN
)))
150 || (numArgs
>= 5 && (!std::isfinite(doubleArguments
[4]) || (doubleArguments
[4] > INT_MAX
) || (doubleArguments
[4] < INT_MIN
)))
151 || (numArgs
>= 6 && (!std::isfinite(doubleArguments
[5]) || (doubleArguments
[5] > INT_MAX
) || (doubleArguments
[5] < INT_MIN
)))
152 || (numArgs
>= 7 && (!std::isfinite(doubleArguments
[6]) || (doubleArguments
[6] > INT_MAX
) || (doubleArguments
[6] < INT_MIN
))))
156 int year
= JSC::toInt32(doubleArguments
[0]);
157 t
.setYear((year
>= 0 && year
<= 99) ? (year
+ 1900) : year
);
158 t
.setMonth(JSC::toInt32(doubleArguments
[1]));
159 t
.setMonthDay((numArgs
>= 3) ? JSC::toInt32(doubleArguments
[2]) : 1);
160 t
.setHour(JSC::toInt32(doubleArguments
[3]));
161 t
.setMinute(JSC::toInt32(doubleArguments
[4]));
162 t
.setSecond(JSC::toInt32(doubleArguments
[5]));
164 double ms
= (numArgs
>= 7) ? doubleArguments
[6] : 0;
165 value
= gregorianDateTimeToMS(vm
, t
, ms
, WTF::LocalTime
);
169 return DateInstance::create(vm
, globalObject
->dateStructure(), value
);
172 static EncodedJSValue JSC_HOST_CALL
constructWithDateConstructor(ExecState
* exec
)
175 return JSValue::encode(constructDate(exec
, asInternalFunction(exec
->callee())->globalObject(), args
));
178 ConstructType
DateConstructor::getConstructData(JSCell
*, ConstructData
& constructData
)
180 constructData
.native
.function
= constructWithDateConstructor
;
181 return ConstructTypeHost
;
185 static EncodedJSValue JSC_HOST_CALL
callDate(ExecState
* exec
)
188 GregorianDateTime ts
;
189 msToGregorianDateTime(vm
, currentTimeMS(), WTF::LocalTime
, ts
);
190 return JSValue::encode(jsNontrivialString(&vm
, formatDateTime(ts
, DateTimeFormatDateAndTime
, false)));
193 CallType
DateConstructor::getCallData(JSCell
*, CallData
& callData
)
195 callData
.native
.function
= callDate
;
199 EncodedJSValue JSC_HOST_CALL
dateParse(ExecState
* exec
)
201 return JSValue::encode(jsNumber(parseDate(exec
->vm(), exec
->argument(0).toString(exec
)->value(exec
))));
204 EncodedJSValue JSC_HOST_CALL
dateNow(ExecState
* exec
)
206 #if !ENABLE(WEB_REPLAY)
210 return JSValue::encode(jsNumber(NORMAL_OR_DETERMINISTIC_FUNCTION(jsCurrentTime(), deterministicCurrentTime(exec
->lexicalGlobalObject()))));
213 EncodedJSValue JSC_HOST_CALL
dateUTC(ExecState
* exec
)
215 double doubleArguments
[7] = {
216 exec
->argument(0).toNumber(exec
),
217 exec
->argument(1).toNumber(exec
),
218 exec
->argument(2).toNumber(exec
),
219 exec
->argument(3).toNumber(exec
),
220 exec
->argument(4).toNumber(exec
),
221 exec
->argument(5).toNumber(exec
),
222 exec
->argument(6).toNumber(exec
)
224 int n
= exec
->argumentCount();
225 if ((std::isnan(doubleArguments
[0]) || (doubleArguments
[0] > INT_MAX
) || (doubleArguments
[0] < INT_MIN
))
226 || (std::isnan(doubleArguments
[1]) || (doubleArguments
[1] > INT_MAX
) || (doubleArguments
[1] < INT_MIN
))
227 || (n
>= 3 && (std::isnan(doubleArguments
[2]) || (doubleArguments
[2] > INT_MAX
) || (doubleArguments
[2] < INT_MIN
)))
228 || (n
>= 4 && (std::isnan(doubleArguments
[3]) || (doubleArguments
[3] > INT_MAX
) || (doubleArguments
[3] < INT_MIN
)))
229 || (n
>= 5 && (std::isnan(doubleArguments
[4]) || (doubleArguments
[4] > INT_MAX
) || (doubleArguments
[4] < INT_MIN
)))
230 || (n
>= 6 && (std::isnan(doubleArguments
[5]) || (doubleArguments
[5] > INT_MAX
) || (doubleArguments
[5] < INT_MIN
)))
231 || (n
>= 7 && (std::isnan(doubleArguments
[6]) || (doubleArguments
[6] > INT_MAX
) || (doubleArguments
[6] < INT_MIN
))))
232 return JSValue::encode(jsNaN());
235 int year
= JSC::toInt32(doubleArguments
[0]);
236 t
.setYear((year
>= 0 && year
<= 99) ? (year
+ 1900) : year
);
237 t
.setMonth(JSC::toInt32(doubleArguments
[1]));
238 t
.setMonthDay((n
>= 3) ? JSC::toInt32(doubleArguments
[2]) : 1);
239 t
.setHour(JSC::toInt32(doubleArguments
[3]));
240 t
.setMinute(JSC::toInt32(doubleArguments
[4]));
241 t
.setSecond(JSC::toInt32(doubleArguments
[5]));
242 double ms
= (n
>= 7) ? doubleArguments
[6] : 0;
243 return JSValue::encode(jsNumber(timeClip(gregorianDateTimeToMS(exec
->vm(), t
, ms
, WTF::UTCTime
))));