static double timeclip(double x) { if (!DUK_ISFINITE(x)) { return DUK_DOUBLE_NAN; } if (x > 8.64e15 || x < -8.64e15) { return DUK_DOUBLE_NAN; } x = duk_js_tointeger_number(x); /* Here we'd have the option to normalize -0 to +0. */ return x; }
/* Compute time value from (double) parts. */ static double get_timeval_from_dparts(double *dparts, int flags) { double tmp_time; double tmp_day; double d; int i; /* Expects 'this' at top of stack on entry. */ /* Coerce all finite parts with ToInteger(). ToInteger() must not * be called for NaN/Infinity because it will convert e.g. NaN to * zero. If ToInteger() has already been called, this has no side * effects and is idempotent. * * Don't read dparts[IDX_WEEKDAY]; it will cause Valgrind issues * if the value is uninitialized. */ for (i = 0; i <= IDX_MILLISECOND; i++) { d = dparts[i]; if (DUK_ISFINITE(d)) { dparts[i] = duk_js_tointeger_number(d); } } /* Use explicit steps in computation to try to ensure that * computation happens with intermediate results coerced to * double values (instead of using something more accurate). * E.g. E5.1 Section 15.9.1.11 requires use of IEEE 754 * rules (= Ecmascript '+' and '*' operators). */ /* MakeTime */ tmp_time = 0; tmp_time += dparts[IDX_HOUR] * ((double) MS_HOUR); tmp_time += dparts[IDX_MINUTE] * ((double) MS_MINUTE); tmp_time += dparts[IDX_SECOND] * ((double) MS_SECOND); tmp_time += dparts[IDX_MILLISECOND]; /* MakeDay */ tmp_day = make_day(dparts[IDX_YEAR], dparts[IDX_MONTH], dparts[IDX_DAY]); /* MakeDate */ d = tmp_day * ((double) MS_DAY) + tmp_time; DUK_DDDPRINT("time=%lf day=%lf --> timeval=%lf", tmp_time, tmp_day, d); /* Optional UTC conversion followed by TimeClip(). * Note that this also handles Infinity -> NaN conversion. */ if (flags & FLAG_LOCALTIME) { /* FIXME: this is now incorrect. 'd' is local time here (as * we're converting to UTC), but GET_LOCAL_TZOFFSET() should * be called with UTC time. This needs to be reworked to avoid * the chicken-and-egg problem. * * See E5.1 Section 15.9.1.9: * UTC(t) = t - LocalTZA - DaylightSavingTA(t - LocalTZA) * * For NaN/inf, GET_LOCAL_TZOFFSET() returns 0. */ d -= GET_LOCAL_TZOFFSET(d) * 1000; } d = timeclip(d); return d; }
DUK_INTERNAL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv) { /* XXX: fastint */ duk_double_t d = duk_js_tonumber(thr, tv); /* invalidates tv */ return duk_js_tointeger_number(d); }
duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv) { duk_double_t d = duk_js_tonumber(thr, tv); /* invalidates tv */ return duk_js_tointeger_number(d); }