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"
44 extern "C" time_t time(time_t* timer
); // Provided by libce.
52 #include <sys/timeb.h>
59 static EncodedJSValue JSC_HOST_CALL
dateParse(ExecState
*);
60 static EncodedJSValue JSC_HOST_CALL
dateNow(ExecState
*);
61 static EncodedJSValue JSC_HOST_CALL
dateUTC(ExecState
*);
65 #include "DateConstructor.lut.h"
69 const ClassInfo
DateConstructor::s_info
= { "Function", &InternalFunction::s_info
, 0, ExecState::dateConstructorTable
, CREATE_METHOD_TABLE(DateConstructor
) };
71 /* Source for DateConstructor.lut.h
72 @begin dateConstructorTable
73 parse dateParse DontEnum|Function 1
74 UTC dateUTC DontEnum|Function 7
75 now dateNow DontEnum|Function 0
79 #if ENABLE(WEB_REPLAY)
80 static double deterministicCurrentTime(JSGlobalObject
* globalObject
)
82 double currentTime
= jsCurrentTime();
83 InputCursor
& cursor
= globalObject
->inputCursor();
84 if (cursor
.isCapturing())
85 cursor
.appendInput
<GetCurrentTime
>(currentTime
);
87 if (cursor
.isReplaying()) {
88 if (GetCurrentTime
* input
= cursor
.fetchInput
<GetCurrentTime
>())
89 currentTime
= input
->currentTime();
95 #if ENABLE(WEB_REPLAY)
96 #define NORMAL_OR_DETERMINISTIC_FUNCTION(a, b) (b)
98 #define NORMAL_OR_DETERMINISTIC_FUNCTION(a, b) (a)
101 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(DateConstructor
);
103 DateConstructor::DateConstructor(VM
& vm
, Structure
* structure
)
104 : InternalFunction(vm
, structure
)
108 void DateConstructor::finishCreation(VM
& vm
, DatePrototype
* datePrototype
)
110 Base::finishCreation(vm
, datePrototype
->classInfo()->className
);
111 putDirectWithoutTransition(vm
, vm
.propertyNames
->prototype
, datePrototype
, DontEnum
| DontDelete
| ReadOnly
);
112 putDirectWithoutTransition(vm
, vm
.propertyNames
->length
, jsNumber(7), ReadOnly
| DontEnum
| DontDelete
);
115 bool DateConstructor::getOwnPropertySlot(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertySlot
&slot
)
117 return getStaticFunctionSlot
<InternalFunction
>(exec
, ExecState::dateConstructorTable(exec
->vm()), jsCast
<DateConstructor
*>(object
), propertyName
, slot
);
121 JSObject
* constructDate(ExecState
* exec
, JSGlobalObject
* globalObject
, const ArgList
& args
)
124 int numArgs
= args
.size();
128 if (numArgs
== 0) // new Date() ECMA 15.9.3.3
129 value
= NORMAL_OR_DETERMINISTIC_FUNCTION(jsCurrentTime(), deterministicCurrentTime(globalObject
));
130 else if (numArgs
== 1) {
131 if (args
.at(0).inherits(DateInstance::info()))
132 value
= asDateInstance(args
.at(0))->internalNumber();
134 JSValue primitive
= args
.at(0).toPrimitive(exec
);
135 if (primitive
.isString())
136 value
= parseDate(vm
, primitive
.getString(exec
));
138 value
= primitive
.toNumber(exec
);
141 double doubleArguments
[7] = {
142 args
.at(0).toNumber(exec
),
143 args
.at(1).toNumber(exec
),
144 args
.at(2).toNumber(exec
),
145 args
.at(3).toNumber(exec
),
146 args
.at(4).toNumber(exec
),
147 args
.at(5).toNumber(exec
),
148 args
.at(6).toNumber(exec
)
150 if ((!std::isfinite(doubleArguments
[0]) || (doubleArguments
[0] > INT_MAX
) || (doubleArguments
[0] < INT_MIN
))
151 || (!std::isfinite(doubleArguments
[1]) || (doubleArguments
[1] > INT_MAX
) || (doubleArguments
[1] < INT_MIN
))
152 || (numArgs
>= 3 && (!std::isfinite(doubleArguments
[2]) || (doubleArguments
[2] > INT_MAX
) || (doubleArguments
[2] < INT_MIN
)))
153 || (numArgs
>= 4 && (!std::isfinite(doubleArguments
[3]) || (doubleArguments
[3] > INT_MAX
) || (doubleArguments
[3] < INT_MIN
)))
154 || (numArgs
>= 5 && (!std::isfinite(doubleArguments
[4]) || (doubleArguments
[4] > INT_MAX
) || (doubleArguments
[4] < INT_MIN
)))
155 || (numArgs
>= 6 && (!std::isfinite(doubleArguments
[5]) || (doubleArguments
[5] > INT_MAX
) || (doubleArguments
[5] < INT_MIN
)))
156 || (numArgs
>= 7 && (!std::isfinite(doubleArguments
[6]) || (doubleArguments
[6] > INT_MAX
) || (doubleArguments
[6] < INT_MIN
))))
160 int year
= JSC::toInt32(doubleArguments
[0]);
161 t
.setYear((year
>= 0 && year
<= 99) ? (year
+ 1900) : year
);
162 t
.setMonth(JSC::toInt32(doubleArguments
[1]));
163 t
.setMonthDay((numArgs
>= 3) ? JSC::toInt32(doubleArguments
[2]) : 1);
164 t
.setHour(JSC::toInt32(doubleArguments
[3]));
165 t
.setMinute(JSC::toInt32(doubleArguments
[4]));
166 t
.setSecond(JSC::toInt32(doubleArguments
[5]));
168 double ms
= (numArgs
>= 7) ? doubleArguments
[6] : 0;
169 value
= gregorianDateTimeToMS(vm
, t
, ms
, false);
173 return DateInstance::create(vm
, globalObject
->dateStructure(), value
);
176 static EncodedJSValue JSC_HOST_CALL
constructWithDateConstructor(ExecState
* exec
)
179 return JSValue::encode(constructDate(exec
, asInternalFunction(exec
->callee())->globalObject(), args
));
182 ConstructType
DateConstructor::getConstructData(JSCell
*, ConstructData
& constructData
)
184 constructData
.native
.function
= constructWithDateConstructor
;
185 return ConstructTypeHost
;
189 static EncodedJSValue JSC_HOST_CALL
callDate(ExecState
* exec
)
192 GregorianDateTime ts
;
193 msToGregorianDateTime(vm
, currentTimeMS(), false, ts
);
194 return JSValue::encode(jsNontrivialString(&vm
, formatDateTime(ts
, DateTimeFormatDateAndTime
, false)));
197 CallType
DateConstructor::getCallData(JSCell
*, CallData
& callData
)
199 callData
.native
.function
= callDate
;
203 static EncodedJSValue JSC_HOST_CALL
dateParse(ExecState
* exec
)
205 return JSValue::encode(jsNumber(parseDate(exec
->vm(), exec
->argument(0).toString(exec
)->value(exec
))));
208 static EncodedJSValue JSC_HOST_CALL
dateNow(ExecState
* exec
)
210 #if !ENABLE(WEB_REPLAY)
214 return JSValue::encode(jsNumber(NORMAL_OR_DETERMINISTIC_FUNCTION(jsCurrentTime(), deterministicCurrentTime(exec
->lexicalGlobalObject()))));
217 static EncodedJSValue JSC_HOST_CALL
dateUTC(ExecState
* exec
)
219 double doubleArguments
[7] = {
220 exec
->argument(0).toNumber(exec
),
221 exec
->argument(1).toNumber(exec
),
222 exec
->argument(2).toNumber(exec
),
223 exec
->argument(3).toNumber(exec
),
224 exec
->argument(4).toNumber(exec
),
225 exec
->argument(5).toNumber(exec
),
226 exec
->argument(6).toNumber(exec
)
228 int n
= exec
->argumentCount();
229 if ((std::isnan(doubleArguments
[0]) || (doubleArguments
[0] > INT_MAX
) || (doubleArguments
[0] < INT_MIN
))
230 || (std::isnan(doubleArguments
[1]) || (doubleArguments
[1] > INT_MAX
) || (doubleArguments
[1] < INT_MIN
))
231 || (n
>= 3 && (std::isnan(doubleArguments
[2]) || (doubleArguments
[2] > INT_MAX
) || (doubleArguments
[2] < INT_MIN
)))
232 || (n
>= 4 && (std::isnan(doubleArguments
[3]) || (doubleArguments
[3] > INT_MAX
) || (doubleArguments
[3] < INT_MIN
)))
233 || (n
>= 5 && (std::isnan(doubleArguments
[4]) || (doubleArguments
[4] > INT_MAX
) || (doubleArguments
[4] < INT_MIN
)))
234 || (n
>= 6 && (std::isnan(doubleArguments
[5]) || (doubleArguments
[5] > INT_MAX
) || (doubleArguments
[5] < INT_MIN
)))
235 || (n
>= 7 && (std::isnan(doubleArguments
[6]) || (doubleArguments
[6] > INT_MAX
) || (doubleArguments
[6] < INT_MIN
))))
236 return JSValue::encode(jsNaN());
239 int year
= JSC::toInt32(doubleArguments
[0]);
240 t
.setYear((year
>= 0 && year
<= 99) ? (year
+ 1900) : year
);
241 t
.setMonth(JSC::toInt32(doubleArguments
[1]));
242 t
.setMonthDay((n
>= 3) ? JSC::toInt32(doubleArguments
[2]) : 1);
243 t
.setHour(JSC::toInt32(doubleArguments
[3]));
244 t
.setMinute(JSC::toInt32(doubleArguments
[4]));
245 t
.setSecond(JSC::toInt32(doubleArguments
[5]));
246 double ms
= (n
>= 7) ? doubleArguments
[6] : 0;
247 return JSValue::encode(jsNumber(timeClip(gregorianDateTimeToMS(exec
->vm(), t
, ms
, true))));