author | Jeff Walden <jwalden@mit.edu> |
Thu, 30 Apr 2015 09:58:58 -0700 | |
changeset 242121 | f35d190d8e2fd0de55a351a804739c2ae6fb8808 |
parent 242120 | a411bd3307dac2f43d9feadd9653fc0a4917e94a |
child 242122 | f703c5483fa01bb6251c826cb2f7417d655ae611 |
push id | 28679 |
push user | philringnalda@gmail.com |
push date | Sat, 02 May 2015 17:02:29 +0000 |
treeherder | mozilla-central@0f5eacc986e8 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | evilpie |
bugs | 1160356 |
milestone | 40.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/jsdate.cpp | file | annotate | diff | comparison | revisions | |
js/src/tests/ecma_5/Date/constructor-convert-all-arguments.js | file | annotate | diff | comparison | revisions |
--- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -569,56 +569,16 @@ RegionMatches(const char* s1, int s1off, /* find UTC time from given date... no 1900 correction! */ static double date_msecFromDate(double year, double mon, double mday, double hour, double min, double sec, double msec) { return MakeDate(MakeDay(year, mon, mday), MakeTime(hour, min, sec, msec)); } -/* compute the time in msec (unclipped) from the given args */ -#define MAXARGS 7 - -static bool -date_msecFromArgs(JSContext* cx, CallArgs args, double* rval) -{ - unsigned loop; - double array[MAXARGS]; - double msec_time; - - for (loop = 0; loop < MAXARGS; loop++) { - if (loop < args.length()) { - double d; - if (!ToNumber(cx, args[loop], &d)) - return false; - /* return NaN if any arg is not finite */ - if (!IsFinite(d)) { - *rval = GenericNaN(); - return true; - } - array[loop] = ToInteger(d); - } else { - if (loop == 2) { - array[loop] = 1; /* Default the date argument to 1. */ - } else { - array[loop] = 0; - } - } - } - - /* adjust 2-digit years into the 20th century */ - if (array[0] >= 0 && array[0] <= 99) - array[0] += 1900; - - msec_time = date_msecFromDate(array[0], array[1], array[2], - array[3], array[4], array[5], array[6]); - *rval = msec_time; - return true; -} - /* ES6 20.3.3.4. */ static bool date_UTC(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); // Steps 1-2. double y; @@ -2942,17 +2902,17 @@ date_valueOf_impl(JSContext* cx, CallArg bool js::date_valueOf(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); return CallNonGenericMethod<IsDate, date_valueOf_impl>(cx, args); } static const JSFunctionSpec date_static_methods[] = { - JS_FN("UTC", date_UTC, MAXARGS,0), + JS_FN("UTC", date_UTC, 7,0), JS_FN("parse", date_parse, 1,0), JS_FN("now", date_now, 0,0), JS_FS_END }; static const JSFunctionSpec date_methods[] = { JS_FN("getTime", date_getTime, 0,0), JS_FN("getTimezoneOffset", date_getTimezoneOffset, 0,0), @@ -3074,27 +3034,86 @@ DateOneArgument(JSContext* cx, const Cal return ToDateString(cx, args, NowAsMillis()); } static bool DateMultipleArguments(JSContext* cx, const CallArgs& args) { MOZ_ASSERT(args.length() >= 2); + // Step 3. if (args.isConstructing()) { - double millis; - if (!date_msecFromArgs(cx, args, &millis)) + // Steps 3a-b. + double y; + if (!ToNumber(cx, args[0], &y)) + return false; + + // Steps 3c-d. + double m; + if (!ToNumber(cx, args[1], &m)) return false; - if (IsFinite(millis)) { - millis = UTC(millis, &cx->runtime()->dateTimeInfo); - millis = TimeClip(millis); + // Steps 3e-f. + double dt; + if (args.length() >= 3) { + if (!ToNumber(cx, args[2], &dt)) + return false; + } else { + dt = 1; + } + + // Steps 3g-h. + double h; + if (args.length() >= 4) { + if (!ToNumber(cx, args[3], &h)) + return false; + } else { + h = 0; + } + + // Steps 3i-j. + double min; + if (args.length() >= 5) { + if (!ToNumber(cx, args[4], &min)) + return false; + } else { + min = 0; } - return NewDateObject(cx, args, millis); + // Steps 3k-l. + double s; + if (args.length() >= 6) { + if (!ToNumber(cx, args[5], &s)) + return false; + } else { + s = 0; + } + + // Steps 3m-n. + double milli; + if (args.length() >= 7) { + if (!ToNumber(cx, args[6], &milli)) + return false; + } else { + milli = 0; + } + + // Step 3o. + double yr = y; + if (!IsNaN(y)) { + double yint = ToInteger(y); + if (0 <= yint && yint <= 99) + yr = 1900 + yint; + } + + // Step 3p. + double finalDate = MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)); + + // Steps 3q-t. + return NewDateObject(cx, args, TimeClip(UTC(finalDate, &cx->runtime()->dateTimeInfo))); } return ToDateString(cx, args, NowAsMillis()); } bool js::DateConstructor(JSContext* cx, unsigned argc, Value* vp) { @@ -3139,17 +3158,17 @@ const Class DateObject::class_ = { nullptr, /* mayResolve */ date_convert, nullptr, /* finalize */ nullptr, /* call */ nullptr, /* hasInstance */ nullptr, /* construct */ nullptr, /* trace */ { - GenericCreateConstructor<DateConstructor, MAXARGS, JSFunction::FinalizeKind>, + GenericCreateConstructor<DateConstructor, 7, JSFunction::FinalizeKind>, GenericCreatePrototype, date_static_methods, nullptr, date_methods, nullptr, FinishDateClassInit } };
new file mode 100644 --- /dev/null +++ b/js/src/tests/ecma_5/Date/constructor-convert-all-arguments.js @@ -0,0 +1,70 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommonn.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 1160356; +var summary = + "new Date(...) must convert *all* arguments to number, not return NaN " + + "early if a non-finite argument is encountered"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function expectThrowTypeError(f, i) +{ + try + { + f(); + throw new Error("didn't throw"); + } + catch (e) + { + assertEq(e, 42, "index " + i + ": expected 42, got " + e); + } +} + +var bad = + { toString: function() { throw 17; }, valueOf: function() { throw 42; } }; + +var funcs = + [ + function() { new Date(bad); }, + + function() { new Date(NaN, bad); }, + function() { new Date(Infinity, bad); }, + function() { new Date(1970, bad); }, + + function() { new Date(1970, NaN, bad); }, + function() { new Date(1970, Infinity, bad); }, + function() { new Date(1970, 4, bad); }, + + function() { new Date(1970, 4, NaN, bad); }, + function() { new Date(1970, 4, Infinity, bad); }, + function() { new Date(1970, 4, 17, bad); }, + + function() { new Date(1970, 4, 17, NaN, bad); }, + function() { new Date(1970, 4, 17, Infinity, bad); }, + function() { new Date(1970, 4, 17, 13, bad); }, + + function() { new Date(1970, 4, 17, 13, NaN, bad); }, + function() { new Date(1970, 4, 17, 13, Infinity, bad); }, + function() { new Date(1970, 4, 17, 13, 37, bad); }, + + function() { new Date(1970, 4, 17, 13, 37, NaN, bad); }, + function() { new Date(1970, 4, 17, 13, 37, Infinity, bad); }, + function() { new Date(1970, 4, 17, 13, 37, 23, bad); }, + ]; + +for (var i = 0, len = funcs.length; i < len; i++) + expectThrowTypeError(funcs[i]); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete");